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