При работе с отчетами в 1С часто возникает необходимость получить данные на определенный момент времени, включая не только дату, но и часы, минуты, секунды. Стандартные механизмы регистров накопления, как правило, ориентированы на получение остатков на "конец дня" или "на определенную дату" без детализации до времени. Однако, если мы имеем дело с периодическим регистром сведений, который хранит данные с точностью до момента времени (например, с периодичностью "Позиция"), нам потребуется особый подход в Системе Компоновки Данных (СКД) для корректного получения среза последних данных.
Давайте подробно рассмотрим, как мы можем настроить СКД для решения этой задачи, используя возможности платформы 1С:Предприятие 8.3. Мы выясним, какие инструменты СКД нам понадобятся, и пошагово разберем процесс настройки, чтобы вы могли применять его в своих проектах.
Прежде всего, давайте разберемся с ключевым инструментом, который поможет нам решить эту задачу – это виртуальная таблица СрезПоследних для регистров сведений. В отличие от регистров накопления, где СрезПоследних также присутствует, для регистров сведений эта таблица имеет несколько иную логику работы. Она предназначена для получения самой актуальной (последней) записи регистра на заданный момент времени для каждой комбинации измерений.
Когда мы обращаемся к РегистрСведений.НашРегистр.СрезПоследних(&МоментВремени, Отбор), платформа 1С выполняет следующий алгоритм:
Период (или другое поле периодичности, если оно настроено) меньше или равно &МоментВремени.Период является максимальным.&МоментВремени для каждого измерения.Это именно то поведение, которое нам необходимо для получения остатков на конкретную дату и время, поскольку СрезПоследних учтет точность до секунды, если сам регистр сведений имеет такую периодичность (например, "Позиция", что позволяет хранить несколько записей на одну дату, но с разным временем).
Начнем с настройки набора данных в схеме компоновки данных. Мы будем использовать конструктор запросов для формирования нашего запроса к регистру сведений. В случаях, когда отчет создается динамически из кода, можно применить СКДБилдер, который упрощает программное создание СКД и делает код значительно более читаемым.
Прежде всего, нам необходимо открыть схему компоновки данных (файл .csd) или создать новую, если вы разрабатываете отчет с нуля. Перейдите на вкладку "Наборы данных" и создайте новый набор данных типа "Запрос".
В конструкторе запросов мы обратимся к нашему периодическому регистру сведений. Предположим, у нас есть регистр сведений ОстаткиНоменклатуры, который хранит измерения Номенклатура и ресурс Количество. Важно, чтобы этот регистр был периодическим, например, с периодичностью "Позиция", чтобы обеспечить точность до времени.
Давайте сформируем запрос. В поле "Таблицы и поля" конструктора запросов найдите ваш регистр сведений и раскройте его. Вы увидите различные виртуальные таблицы, среди которых будет СрезПоследних. Выберите эту виртуальную таблицу.
Перенесем необходимые поля в секцию "Выбранные поля", например, Номенклатура и Количество. Теперь нам нужно правильно настроить параметры виртуальных таблиц в компоновке данных, в частности для таблицы СрезПоследних. В конструкторе запросов, после выбора СрезПоследних, у вас появится возможность указать параметры для этой таблицы. Нам потребуется передать параметр, который будет определять момент среза. Назовем его, например, МоментОтчета.
В результате ваш запрос будет выглядеть примерно так:
ВЫБРАТЬ
ОстаткиНоменклатурыСрезПоследних.Номенклатура,
ОстаткиНоменклатурыСрезПоследних.Количество
ИЗ
РегистрСведений.ОстаткиНоменклатуры.СрезПоследних(&МоментОтчета, ) КАК ОстаткиНоменклатурыСрезПоследних
Обратите внимание, что второй параметр в СрезПоследних (который отвечает за отбор по измерениям) мы оставили пустым. Это означает, что отбор по измерениям применяться не будет, и срез будет построен для всех записей. Если вам потребуется дополнительный отбор (например, по определенным группам номенклатуры), его можно добавить либо во второй параметр СрезПоследних, либо в секцию "ГДЕ" основного запроса СКД.
После того как запрос сформирован, нам необходимо определить и настроить параметр &МоментОтчета в самой схеме компоновки данных. Это критически важный этап, поскольку именно здесь мы указываем, что наш параметр должен принимать значение даты с точностью до времени.
МоментОтчета. Если он не появился автоматически после создания запроса, добавьте его вручную, нажав кнопку "Добавить" и указав имя МоментОтчета.
МоментОтчета обязательно установите Тип значения в Дата. Это основа корректной работы с датами и моментами времени в 1С:Предприятие 8.3, что позволит передавать в параметр значения как даты, так и даты со временем.
Для того чтобы пользователь мог удобно указывать дату и время в отчете, нам нужно убедиться, что поле ввода параметра будет отображать и позволять вводить время. Обычно, если тип параметра установлен как Дата, платформа автоматически определяет, отображать ли время, исходя из используемых данных или настроек конфигурации. Однако, мы можем явно повлиять на это:
Дата указан подходящий вариант, если это возможно. Часто достаточно просто установить тип Дата, и система сама подстроит ввод.
Использовать всегда для параметра МоментОтчета. Это гарантирует, что параметр всегда будет доступен для установки пользователем, даже если он явно не добавлен в пользовательские настройки отчета.
МоментОтчета в большинстве случаев подходит Равно или МеньшеИлиРавно (если вы хотите дать пользователю возможность указать, что срез делается *по* эту дату/время включительно). В контексте СрезПоследних, Равно вполне достаточно, так как функция сама берет записи <= указанного момента.
НачалоДня(ТекущаяДата()) или КонецДня(ТекущаяДата()), или просто ТекущаяДата(), если вы хотите, чтобы по умолчанию отображались текущие дата и время.
Чтобы пользователь мог изменять МоментОтчета непосредственно из формы отчета, нам необходимо добавить этот параметр в пользовательские настройки. Грамотная настройка пользовательских полей и параметров в СКД позволит вынести этот фильтр в удобную для пользователя область формы.
МоментОтчета из списка доступных полей и параметров на вкладке "Поля" в ветку "Параметры" в пользовательских настройках.
После этих настроек, при формировании отчета, пользователь увидит поле для ввода даты и времени, через которое сможет указать нужный момент для среза данных.
При использовании этого подхода мы должны учитывать несколько важных моментов, чтобы обеспечить корректную работу и ожидаемые результаты:
Ключевым условием для точной работы с временем является правильная периодичность самого регистра сведений. Если ваш регистр сведений имеет периодичность "Позиция", это означает, что он может хранить несколько записей на одну и ту же дату, но с разным временем, и СрезПоследних будет работать с точностью до секунды.
Если же регистр имеет периодичность "День", "Месяц" или "Год", то указание времени в параметре МоментОтчета будет иметь ограниченный смысл. СрезПоследних все равно найдет последнюю запись до указанного момента, но если все записи за день имеют одинаковое время (например, начало дня), то выбор будет происходить только по дню. Всегда проверяйте настройки периодичности вашего регистра сведений.
СрезПоследних с пустыми данными:
Что произойдет, если на указанный &МоментОтчета нет ни одной записи или все записи находятся после этого момента? В таком случае виртуальная таблица СрезПоследних просто не вернет никаких данных для соответствующих измерений. Это нормальное и ожидаемое поведение.
В некоторых случаях бывает полезно преобразовать настройки из динамического списка в отчет СКД, чтобы быстро получить детальный срез по тем позициям, которые пользователь уже отфильтровал в экранной форме. Это значительно экономит время при переходе от оперативной работы к аналитике.
Иногда возникают ситуации, когда отчет должен игнорировать ограничения прав доступа на уровне записей (RLS) для получения полных данных. В таких случаях можно использовать СКД в привилегированном режиме, что позволяет корректно сформировать срез последних даже при строгих настройках безопасности.
Рассмотрим, где такой подход может быть особенно полезен:
СрезПоследних, чтобы получить актуальные цены на любой заданный момент времени для анализа динамики или проверки правильности расчета.
СрезПоследних будут идеальным решением.
Теоретически, можно было бы попытаться получить тот же результат, используя обычный запрос к регистру сведений без виртуальных таблиц, комбинируя вложенные запросы и агрегатные функции, такие как МАКСИМУМ(Период). Однако, такой запрос будет значительно менее производительным. Платформа 1С оптимизирована для работы с виртуальными таблицами, и СрезПоследних использует внутренние индексы и механизмы для быстрого получения данных.
В более сложных архитектурных задачах может потребоваться использовать две разных схемы в одном отчете СКД, например, для вывода основного среза данных и сравнительной таблицы по другой методике в рамках одного отчета. Это "искусство ради искусства", но иногда оправдано требованиями бизнеса.
Поэтому мы настоятельно рекомендуем использовать именно виртуальную таблицу СрезПоследних, как наиболее эффективное и производительное решение для данной задачи.
Мы подробно разобрали, как эффективно настроить Систему Компоновки Данных для получения среза последних данных из периодического регистра сведений на заданную дату и время. Использование виртуальной таблицы СрезПоследних в сочетании с правильно настроенным параметром СКД типа Дата (с учетом времени) позволяет добиться требуемой точности и оперативности в отчетности.
Этот подход является стандартным и наиболее оптимальным для решения задач, где критически важен именно момент времени для получения актуальных данных. Применяя эти знания, вы сможете создавать гибкие и точные отчеты, удовлетворяющие самым взыскательным требованиям бизнеса в системе 1С:Предприятие.