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

Программист 1С v8.3 (Управляемые формы) 1С:Зарплата и Управление Персоналом Управленческий учет
← На главную

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

В чем ошибка при использовании СрезПоследних?

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

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

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

Решение проблемы: обращение к основной таблице регистра

Чтобы увидеть не просто состояние "на момент", а именно историю всех событий, произошедших внутри временного интервала, мы должны обратиться к основной (физической) таблице регистра. В отличие от виртуальных таблиц, основная таблица содержит абсолютно все записи, которые когда-либо были записаны в базу (с учетом активности).

Разберем правильный подход по шагам. Вместо обращения к РегистрСведений.Проц.СрезПоследних, мы используем РегистрСведений.Проц. Давайте посмотрим на исправленный пример кода:


Запрос.Текст = 
    "ВЫБРАТЬ
    |    Проц.Период,
    |    Проц.Орг,
    |    Проц.Подр КАК Подр,
    |    Проц.Должн КАК Должн,
    |    Проц.Оклад,
    |    Проц.Проц,
    |    Проц.План1,
    |    Проц.План2
    |ИЗ
    |    РегистрСведений.Проц КАК Проц
    |ГДЕ
    |    Проц.Подр = &ВыбПодр
    |    И Проц.Должн = &ВыбДолжн
    |    И Проц.Период МЕЖДУ &д1 И &д2
    |
    |УПОРЯДОЧИТЬ ПО
    |    Период,
    |    Подр,
    |    Должн";

В данном запросе мы используем условие МЕЖДУ для фильтрации по полю Период. Это позволяет системе выбрать все строки, дата которых попадает в заданный диапазон.

Важный нюанс: Проверка активности записей

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

Почему это важно? Когда вы используете СрезПоследних, платформа 1С автоматически отсеивает неактивные записи (например, те, документы по которым были отменены в проведении или помечены на удаление). Однако при прямом обращении к таблице РегистрСведений.Проц, в выборку попадут все записи, включая неактивные. Чтобы ваш отчет или алгоритм не использовал "мусорные" данные, необходимо обязательно добавлять проверку условия Активность.

Правильнее будет дополнить блок ГДЕ следующим образом:


ГДЕ
    Проц.Подр = &ВыбПодр
    И Проц.Должн = &ВыбДолжн
    И Проц.Период МЕЖДУ &д1 И &д2
    И Проц.Активность = ИСТИНА

Оптимизация работы с периодом

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

  1. Параметр &д1 — Начало дня (01.01.2023 00:00:00).
  2. Параметр &д2 — Конец дня (01.01.2023 23:59:59).

Для установки этих параметров в коде 1С удобно использовать встроенные функции:


Запрос.УстановитьПараметр("д1", НачалоДня(ВыбДата));
Запрос.УстановитьПараметр("д2", КонецДня(ВыбДата));

Также стоит отметить оператор МЕЖДУ. Как заметили участники обсуждения, использование Период >= &д1 И Период <= &д2 идентично оператору МЕЖДУ, но второй вариант делает код более читаемым и коротким.

Работа с Регистратором

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

Рассмотрим пример добавления регистратора в выборку:


ВЫБРАТЬ
    Проц.Период,
    Проц.Регистратор,
    Проц.Оклад
ИЗ
    РегистрСведений.Проц КАК Проц
ГДЕ
    Проц.Период МЕЖДУ &Начало И &Конец

Индексы и производительность

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

Подведем итоги

Для успешного решения задачи по чтению данных из периодического регистра за день мы должны придерживаться следующих правил:

  1. Забыть про СрезПоследних, если нам нужна история изменений, а не состояние на момент.
  2. Обращаться к физической таблице регистра (имя регистра без дополнений).
  3. Устанавливать границы периода через НачалоДня и КонецДня.
  4. Не забывать про фильтр Активность, чтобы исключить записи отмененных документов.
  5. Использовать упорядочивание по периоду, чтобы данные в выборке шли в хронологическом порядке.

Соблюдение этих простых шагов гарантирует получение точных и полных данных из периодических регистров сведений в любых конфигурациях на базе 1С:Предприятие 8.

← На главную