В практике разработки на платформе 1С:Предприятие начинающие специалисты часто сталкиваются с ситуацией, когда при построении отчета по регистру накопления данные либо не фильтруются по периоду, либо в списке доступных полей отсутствуют нужные реквизиты. Разберем детально, почему так происходит, и как правильно спроектировать запрос, чтобы отчет работал быстро и корректно.
Для начала проанализируем, как 1С хранит данные. Когда мы выбираем в конструкторе запроса таблицу вида РегистрНакопления.ИмяРегистра, мы обращаемся к так называемой физической таблице. Это «сырые» записи всех движений, которые когда-либо делали документы. В этой таблице нет встроенных механизмов быстрого расчета итогов.
Если мы используем физическую таблицу, то для фильтрации по датам нам необходимо самостоятельно прописывать условия в секции ГДЕ. Рассмотрим пример кода:
ВЫБРАТЬ
РегистрПродажи.Период,
РегистрПродажи.Номенклатура,
РегистрПродажи.Количество
ИЗ
РегистрНакопления.Продажи КАК РегистрПродажи
ГДЕ
РегистрПродажи.Период МЕЖДУ &НачалоПериода И &КонецПериода
Однако такой подход неэффективен для получения остатков или оборотов за большой период. Для этих целей платформа предоставляет виртуальные таблицы, такие как Обороты, Остатки и ОстаткиИОбороты. Именно в них параметры периода передаются не через условия ГДЕ, а непосредственно в параметры самой таблицы, что позволяет системе использовать заранее рассчитанные итоги.
Если вы работаете в Системе Компоновки Данных (СКД) и используете виртуальные таблицы, важно правильно настроить параметры. Разберем по шагам, как это сделать:
РегистрНакопления.Продажи.Обороты.&НачалоПериода и &КонецПериода.Рассмотрим полезный прием: как сделать так, чтобы при незаполненном периоде выводились данные за все время. Для этого в тексте запроса СКД используем фигурные скобки, которые делают условия необязательными:
ВЫБРАТЬ
ПродажиОбороты.Номенклатура,
ПродажиОбороты.КоличествоОборот
ИЗ
РегистрНакопления.Продажи.Обороты({&НачалоПериода}, {&КонецПериода}) КАК ПродажиОбороты
Совет: Для удобства пользователя лучше создать один параметр с типом СтандартныйПериод (назовем его ПериодОтчета), а для технических параметров НачалоПериода и КонецПериода в колонке «Выражение» прописать &ПериодОтчета.ДатаНачала и &ПериодОтчета.ДатаОкончания соответственно.
Часто программисты замечают, что в таблице Обороты нельзя выбрать Комментарий или другие реквизиты регистра. Это происходит потому, что виртуальная таблица группирует данные по измерениям. Реквизиты не являются ключевыми полями для расчета итогов, поэтому они «отсекаются» при агрегации.
Проанализируем два правильных способа решения этой проблемы, чтобы не превращать все реквизиты в Измерения (что является грубой ошибкой, замедляющей работу базы):
Если вам нужно получить данные из документа, который сделал движение, выполните следующие действия:
Обороты) установите периодичность Регистратор.Регистратор.Регистратор.Комментарий, Регистратор.Ответственный и так далее.Если данные хранятся именно в реквизитах самого регистра, а не в документе, мы можем использовать соединение. Рассмотрим пример запроса:
ВЫБРАТЬ
ПродажиОбороты.Номенклатура,
ПродажиОбороты.КоличествоОборот,
ПродажиФизическаяТаблица.ДополнительноеОписание
ИЗ
РегистрНакопления.Продажи.Обороты(&Начало, &Конец) КАК ПродажиОбороты
ЛЕВОЕ СОЕДИНЕНИЕ РегистрНакопления.Продажи КАК ПродажиФизическаяТаблица
ПО ПродажиОбороты.Регистратор = ПродажиФизическаяТаблица.Регистратор
И ПродажиОбороты.НомерСтроки = ПродажиФизическаяТаблица.НомерСтроки
Такой подход позволяет нам пользоваться всеми преимуществами быстрой виртуальной таблицы (для получения сумм) и одновременно вытягивать текстовые или описательные данные из основной таблицы записей.
Выясним причину, почему нельзя всё подряд записывать в измерения. Каждое Измерение в 1С автоматически индексируется и участвует в расчете итогов. Если вы добавите текстовое поле (например, «Адрес доставки») в измерения:
Важное правило: В измерения выносим только то, по чему мы планируем получать остатки и обороты в разрезе (Склад, Номенклатура, Контрагент). Всё остальное — в реквизиты.
Если вы обнаружили, что в вашем регистре накопления вам не нужны ресурсы (вы не суммируете количество или суммы), а нужны только данные за период с описанием действий — вы выбрали неверный объект метаданных. В этом случае лучше использовать Регистр Сведений. Он потребляет меньше ресурсов сервера, а работа с периодами в нем является штатной функцией, так как период там по умолчанию является частью ключа записи.
Подводя итог, помните: для получения числовых показателей за период всегда используйте виртуальные таблицы с параметрами, а для получения описательных данных используйте обращение через Регистратор или соединения. Это обеспечит баланс между функциональностью и производительностью вашей системы.