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

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

Основы работы с объектом регистр сведений

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

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

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

💡

Всегда проверяйте свойство "Периодический" у регистра сведений перед написанием кода выборки. Это свойство диктует необходимость указания периода или использования срезов.

⚠️ Внимание: При работе с большими регистрами сведений (миллионы записей) использование метода Выбрать() без условий отбора может привести к зависанию клиентского приложения из-за передачи огромного массива данных по сети.

Полный перебор записей без условий отбора

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

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

Выборка = РегистрыСведений.КурсыВалют.Выбрать();

Пока Выборка.Следующий() Цикл

Сообщить(Выборка.Валюта + ": " + Выборка.Курс);

КонецЦикла;

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

📊 Какой метод выборки вы используете чаще всего?
ВыборкаДанных (Выбрать)
Запрос (Объект Запрос)
СрезПоследних
Табличный документ

Использование срезов для получения актуальных данных

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

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

  • 📅 Указание точной даты позволяет получить снимок состояния системы на конец дня.
  • ⏳ Использование текущего времени (ТекущаяДата()) дает актуальные данные на момент запуска кода.
  • 📉 Метод автоматически фильтрует дубликаты, оставляя только последние версии записей для каждого набора измерений.

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

💡

Использование СрезПоследних вместо полной выборки может ускорить выполнение кода в десятки раз на больших базах данных за счет оптимизации SQL-запроса на стороне СУБД.

Оптимизация выборки с помощью объекта Запрос

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

Для перебора записей через запрос необходимо создать текст запроса, где в секции ВЫБРАТЬ указываются нужные поля, а в секции ИЗ — виртуальная таблица регистра сведений. Особенностью работы с регистрами в запросах является возможность использования виртуальных таблиц, таких как СрезПоследних или СрезПервых, прямо в тексте запроса.

ТекстЗапроса = 

"ВЫБРАТЬ

| КурсыВалютСрезПоследних.Валюта,

| КурсыВалютСрезПоследних.Курс

|ИЗ

| РегистрСведений.КурсыВалют.СрезПоследних(&ДатаСреза) КАК КурсыВалютСрезПоследних";

Запрос = Новый Запрос(ТекстЗапроса);

Запрос.УстановитьПараметр("ДатаСреза", ТекущаяДата());

Результат = Запрос.Выполнить();

ВыборкаДетальныеЗаписи = Результат.Выбрать();

После выполнения запроса мы получаем объект Результат, из которого можно извлечь выборку. Такой подход дает возможность добавлять условия ГДЕ, группировать данные с помощью СГРУППИРОВАТЬ ПО и сортировать результаты. Это незаменимый инструмент для сложных отчетов и обработок данных.

Почему запросы быстрее выборок?

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

Обработка многомерных регистров и отборы

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

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

Метод фильтрации Где выполняется Влияние на сеть Рекомендация
Отбор выборки Сервер БД Минимальное Всегда использовать в первую очередь
Условие в цикле (Если..Тогда) Клиент/Сервер 1С Высокое (передаются все данные) Только для сложной логики, недоступной в отборе
Параметры запроса Сервер БД Минимальное Оптимально для объектов Запрос

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

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

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

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

Также следует избегать вложенных циклов, где внутри перебора одного регистра происходит выборка из другого регистра или справочника по каждой записи. Это классическая проблема "N+1 запроса", которая убивает производительность. Вместо этого следует использовать временные таблицы или объединять данные с помощью запросов с соединениями (ЛЕВОЕ СОЕДИНЕНИЕ).

  • 🚀 Используйте режим ДляИзменения только если реально планируете записывать изменения.
  • 🛑 Избегайте вызова тяжелых функций или обращений к HTTP-сервисам внутри цикла перебора.
  • 💾 Сбрасывайте выборку в null после окончания работы для освобождения ресурсов сервера.

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

☑️ Чек-лист оптимизации перебора

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

⚠️ Внимание: Интерфейс и возможности консоли запросов могут отличаться в зависимости от версии платформы 1С и используемой СУБД (MSSQL, PostgreSQL, Oracle). Всегда сверяйте синтаксис с актуальной документацией для вашей версии.

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

В чем разница между Выборкой и Запросом в 1С?

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

Как получить количество записей в регистре сведений?

Для получения количества записей лучше всего использовать объект Запрос с функцией КОЛИЧЕСТВО(*). Попытка перебрать все записи циклом только для подсчета их количества крайне неэффективна и нагружает систему.

Можно ли изменять запись в цикле Выборка.Следующий()?

Да, можно, но только если выборка была создана в режиме ДляИзменения. Например: Регистр.Выбрать(, , РежимВыборки.ДляИзменения). Без этого режима попытка записи вызовет исключение.

Что такое виртуальная таблица СрезПоследних?

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

Почему выборка работает медленно на большой базе?

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