Заполняем регистр сведений: от ручного ввода до загрузки из файла

· 9 мин

Содержание

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

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

Из чего состоит регистр сведений и что в нём можно хранить

Регистр сведений — это таблица с жёстко заданным ключом. В отличие от справочника, у записи нет собственной ссылки: её однозначно определяет набор измерений (плюс период, если регистр периодический).

ЭлементРоль
🔑 ИзмеренияКлюч записи. Комбинация значений измерений уникальна
📊 РесурсыХранимые значения: цена, курс, настройка
📝 РеквизитыДополнительная информация, в ключ не входит
📅 ПериодДата записи у периодического регистра

Два свойства регистра задают, как в него можно писать:

  • Периодичность — непериодический или с привязкой к дате: в пределах секунды, дня, месяца, квартала, года. У периодического регистра поле Период обязательно для заполнения.
  • Режим записи — Независимый или Подчинение регистратору. От него зависит, можно ли вводить данные вручную и каким кодом их писать.

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

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

Ручной ввод записей через форму списка

Для независимого регистра сведений записи вводятся прямо в его форме списка.

  1. Откройте список регистра. Если для него не выведена отдельная команда в панели разделов, используйте меню Главное меню → Все функции → Регистры сведений и выберите нужный регистр по имени.
  2. Нажмите Создать — откроется форма записи.
  3. Заполните все измерения, ресурсы и реквизиты. У периодического регистра укажите Период.
  4. Запишите и закройте.

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

Команда Все функции доступна, когда она включена в параметрах: Главное меню → Сервис → Параметры → Отображать команду «Все функции». Без неё к служебным регистрам из интерфейса не добраться — только через код или отдельную форму обработки.

Запись из встроенного языка: менеджер записи и набор записей

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

Менеджер записи удобен, когда нужно создать или обновить ровно одну строку:

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

Параметр метода Записать отвечает за замещение. При Истина существующая запись с таким ключом перезаписывается. При Ложь и уже имеющейся записи 1С вернёт ошибку, что запись с такими ключевыми полями существует.

Набор записей пишет сразу несколько строк и может заместить все записи по отбору:

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

Строка = Набор.Добавить();
Строка.Период = НачалоДня(ТекущаяДата());
Строка.Валюта = Валюта;
Строка.Курс   = 75.5;

Набор.Записать(Истина); // заместит ВСЕ записи по отбору Валюта

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

Для регистра, подчинённого регистратору, записи формируются в модуле документа при проведении — через коллекцию движений:

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

Платформа сама запишет такие движения при завершении проведения, если у движений выставлено Записывать = Истина.

У регистра, подчинённого регистратору, есть служебное поле Активность. Запись с Активность = Ложь физически в таблице остаётся, но срезы её игнорируют. Именно так платформа гасит движения при распроведении документа — строки не удаляются, а помечаются неактивными. У независимого регистра поля Активность нет.

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

Какой способ записи выбрать?

Загрузка большого объёма данных из внешнего файла

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

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

Несколько приёмов для больших загрузок:

  • 📦 Если строки для одного значения отбора можно записать разом — используйте набор записей: один Записать() вместо множества менеджеров быстрее.
  • 🧮 Делите загрузку на пачки (например, по несколько тысяч записей на транзакцию), чтобы не держать одну гигантскую транзакцию.
  • 🔁 Устанавливайте МЗ.ОбменДанными.Загрузка = Истина перед записью, когда нужно пропустить проверки заполнения и не вызывать обработчики. Применяйте осознанно: так в базу можно занести и некорректные данные.

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

Периодичность и получение актуального значения на дату

У периодического регистра запись привязана к дате. Чтобы получить значение, действующее на определённый момент, используют срезы.

  • Срез последних — последняя по времени запись на указанную дату и раньше.
  • Срез первых — первая запись начиная с указанной даты.

В коде срез последних можно получить методом менеджера:

Отбор = Новый Структура("Номенклатура", Номенклатура);
ТаблицаЦен = РегистрыСведений.Цены.СрезПоследних(ДатаРасчёта, Отбор);

Чаще срез берут в запросе через виртуальную таблицу — так можно соединять его с другими данными:

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

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

ТаблицаПервых = РегистрыСведений.Цены.СрезПервых(ДатаНачала, Отбор);

Если нужно значение на точную дату (без «последней до»), подойдёт метод Получить(Период, Отбор) — он вернёт структуру ресурсов для записи с этим ключом и периодом.

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

Отдельно стоит ведущее измерение. Когда объект, указанный в ведущем измерении, удаляется, платформа автоматически удаляет связанные с ним записи регистра. Это свойство задаётся у измерения в конфигураторе и избавляет от «висящих» строк.

Изменение и удаление существующих записей

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

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

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

Удалить одну запись можно методом Удалить() у заполненного по ключу менеджера:

МЗ.Удалить();

Удалить все записи по условию проще пустым набором с замещением:

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

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

Почему запись не проходит: разбор ошибок

Диагностика: выберите симптом

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

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

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