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

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

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

Архитектура и назначение объекта НаборЗаписей

Объект НаборЗаписей (в коде часто обозначается как RecordSet) является специализированным контейнером. Его главная задача — буферизировать изменения перед их фактической фиксацией в таблице базы данных. Когда вы создаете этот объект, система считывает структуру выбранного регистра и формирует объект, который «знает», какие поля обязательны, какие имеют тип, а какие являются служебными.

Важно отметить, что данный объект не существует сам по себе в отрыве от регистра. Вы всегда создаете его для конкретного регистра сведений, накопления или бухгалтерии. Это отличает его от универсальных структур данных, таких как Массив или ТаблицаЗначений, которые могут хранить любые данные. Здесь же жесткая типизация гарантируется на уровне метаданных.

Использование набора записей существенно повышает производительность системы. Вместо того чтобы выполнять hundreds отдельных SQL-запросов на вставку каждой строки, платформа формирует один оптимизированный пакетный запрос. Это критически важно в высоконагруженных системах, где каждая миллисекунда на счету.

⚠️ Внимание: Не пытайтесь использовать набор записей для простого хранения временных данных, если они не предназначены для записи в регистр. Для временных вычислений лучше подойдут таблицы значений, так как накладные расходы на инициализацию набора записей выше.

💡

При работе с регистрами накопления всегда проверяйте тип регистра (остатки или обороты), так как структура набора записей будет автоматически подстраиваться под требуемые измерения и ресурсы.

Создание и инициализация набора записей

Процесс создания объекта начинается с получения ссылки на метаданные регистра. В коде конфигурации это обычно делается через глобальный контекст или непосредственно через имя регистра. Синтаксис создания предельно прост, но требует точного указания имени регистра.

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

Набор = Документы.РеализацияТоваровУслуг.НаборыДвижений.Товары;

Набор.Записать;

Однако чаще всего требуется создать набор программно для произвольного регистра. Для этого используется конструктор объекта. Вам необходимо наполнить его данными перед вызовом метода записи.

  • 🔹 Использование конструктора Новый НаборЗаписейРегистраСведений требует передачи объекта метаданных.
  • 🔹 Альтернативный способ — получение через свойство Движения документа, что автоматически связывает набор с конкретным проведением.
  • 🔹 Инициализация может происходить как на клиенте, так и на сервере, но запись возможна только в серверном контексте.

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

📊 Как вы чаще всего создаете наборы записей?
Через конструктор Нового
Через движения документа
Через запрос с заполнением
Использую готовые обработки

Заполнение данными и работа со свойствами

После успешной инициализации наступает этап наполнения данными. Объект НаборЗаписей ведет себя как коллекция. Вы можете добавлять новые строки, используя метод Добавить, который возвращает ссылку на новый элемент набора. Именно в этот элемент вы записываете значения полей.

Каждая строка набора строго соответствует структуре регистра. Это значит, что вы имеете прямой доступ к измерениям, ресурсам и реквизитам. Попытка присвоить значение несоответствующего типа вызовет ошибку выполнения. Например, нельзя записать строку в числовое поле ресурса.

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

Свойство/Метод Назначение Тип возвращаемого значения
Добавить Создает новую строку в наборе ЗаписьНабораЗаписей
Записать Фиксирует изменения в базе данных Не возвращает значения
Отбор Фильтр для выборки существующих записей СтруктураОтбора
Заполнить Массовое заполнение из таблицы значений Не возвращает значения

Особое внимание стоит уделить методу Заполнить. Он позволяет массово перенести данные из ТаблицыЗначений в набор записей. Это крайне удобно при обработке данных, полученных из внешних источников или результатыв queries. Система автоматически сопоставит колонки таблицы с полями регистра по именам.

⚠️ Внимание: При использовании метода Заполнить убедитесь, что имена колонок в таблице значений точно совпадают с именами полей регистра. Регистр чувствителен к регистру букв в именах полей, и несовпадение приведет к тому, что поле останется пустым.

Управление отбором и фильтрация записей

Часто возникает ситуация, когда необходимо не добавить новые записи, а найти и изменить или удалить существующие. Для этих целей в объекте предусмотрен мощный механизм отбора. Свойство Отбор позволяет задать условия, по которым будут выбираться записи из базы данных при чтении набора.

Вы можете устанавливать условия равенства, неравенства, вхождения в список и другие операторы сравнения. Это позволяет эффективно работать с подмножествами данных, не загружая в память лишнюю информацию. Фильтрация происходит на стороне СУБД, что гарантирует высокую скорость работы.

Пример установки отбора выглядит следующим образом:

Набор.Отбор.Период.Установить(Равно, ТекущаяДата);

Набор.Отбор.Контрагент.Установить(ВСписке, СписокКонтрагентов);

Набор.Прочитать;

После установки отбора необходимо вызвать метод Прочитать. Только после этого коллекция наполнится данными из базы, соответствующими заданным критериям. Без вызова этого метода набор останется пустым, даже если отбор настроен верно.

  • 🔸 Отбор можно сбросить методом Очистить, чтобы считать все записи регистра.
  • 🔸 Условия отбора поддерживают логические связки, позволяя строить сложные фильтры.
  • 🔸 Использование отбора критически важно для производительности при работе с большими регистрами.
Почему отбор лучше ставить до чтения?

Установка отбора до вызова метода Прочитать формирует SQL-запрос с конструкцией WHERE. Если установить отбор после чтения, фильтрация произойдет в памяти 1С, что при больших объемах данных приведет к падению производительности и перерасходу оперативной памяти.

Запись изменений и транзакционная безопасность

Финальным этапом работы является сохранение изменений. Метод Записать отправляет все накопленные в наборе изменения в базу данных. Поведение этого метода зависит от режима записи, который можно задать через свойство РежимЗаписи.

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

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

⚠️ Внимание: Интерфейсы и возможности платформы 1С могут обновляться. Детали реализации метода Записать в новых версиях платформы (например, 8.3.25+) могут отличаться оптимизацией блокировок. Всегда сверяйте поведение в документации к конкретной версии платформы, которую вы используете в продакшене.

💡

Запись набора записей вне транзакции допустима только для регистров сведений, не влияющих на расчеты. Для регистров накопления и бухгалтерии использование транзакции обязательно.

Типичные ошибки и оптимизация производительности

При работе с НаборЗаписей разработчики часто сталкиваются с рядом типичных проблем. Одна из самых распространенных — попытка записи дублирующихся ключевых полей в регистры сведений без включения соответствующего режима замены. Это приводит к ошибке нарушения уникальности.

Другая частая ошибка — чтение всего регистра без отбора в цикле. Если в регистре миллионы записей, такая операция может «положить» сервер. Всегда используйте отбор по периоду или ключевым измерениям. Также стоит избегать частых вызовов метода Записать внутри циклов; лучше накопить данные и записать их одним пакетом.

Оптимизация также касается работы с реквизитами. Не обращайтесь к полям записи через строковые имена (например, Запись["Поле"]), если есть возможность использовать точечную нотацию (Запись.Поле). Динамическое обращение к свойствам через строку работает медленнее из-за затрат на парсинг имени.

  • 🚫 Избегайте записи в цикле по одной записи.
  • 🚫 Не игнорируйте индексы регистра при построении отборов.
  • 🚫 Не забывайте освобождать память, обнуляя ссылки на большие наборы после использования.

Для диагностики проблем с записью рекомендуется использовать технологический журнал (ТЖ). Он позволяет отследить длительность выполнения SQL-запросов, генерируемых методом записи, и выявить узкие места в структуре регистра или индексах базы данных.

☑️ Чек-лист перед записью набора

Выполнено: 0 / 5

Часто задаваемые вопросы (FAQ)

В чем разница между НаборЗаписей и РегистрЗаписей?

НаборЗаписей — это объект в памяти программы, буфер для изменений. РегистрЗаписей (или просто регистр) — это объект метаданных, описывающий структуру хранения данных в базе. Вы используете НаборЗаписей, чтобы взаимодействовать с данными конкретного Регистра.

Можно ли прочитать данные из регистра, не создавая набор записей?

Да, для чтения данных чаще и эффективнее использовать объект Запрос. НаборЗаписей для записи и модификации данных. Чтение через набор записей удобно только когда нужно сразу же модифицировать считанные строки и записать их обратно.

Что произойдет, если не вызвать метод Прочитать после установки отбора?

Коллекция набора записей останется пустой. Метод Прочитать является триггером, который отправляет запрос к базе данных. Без него отбор существует только в свойствах объекта, но не применяется к данным.

Как удалить записи из регистра с помощью набора?

Необходимо установить отбор на нужные записи, вызвать Прочитать, затем установить свойство РежимЗаписи в значение Удаление и вызвать Записать. Либо можно пометить считанные строки на удаление и записать в режиме изменения.

Поддерживает ли набор записей работу с виртуальными таблицами?

Нет, НаборЗаписей работает только с физическими таблицами регистров. Для работы с виртуальными таблицами (например, «ОстатыНаКонецПериода») необходимо использовать объект Запрос, так как виртуальные таблицы являются результатом вычислений, а не местом хранения.