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