Как выбрать только одну последнюю запись из регистра сведений в динамическом списке 1С

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

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

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

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

Решение 1: Использование вложенного запроса с агрегацией

Для того чтобы оставить только одну запись, нам нужно самостоятельно определить критерий «единственности». Чаще всего это максимальный период. Посмотрим на пример того, как можно реализовать это в тексте запроса динамического списка. Поскольку динамические списки не поддерживают временные таблицы (инструкция ПОМЕСТИТЬ), мы будем использовать вложенный запрос.

Рассмотрим следующий алгоритм построения запроса:

  1. Создаем вложенный запрос, который выбирает максимальную дату (МАКСИМУМ(Период)) для каждого основного объекта (например, номенклатуры или программы).
  2. Соединяем этот вложенный запрос с основной физической таблицей регистра по полям «Объект» и «Период».

ВЫБРАТЬ
    РегистрВерсии.Период КАК Период,
    РегистрВерсии.Программа КАК Программа,
    РегистрВерсии.Версия КАК Версия
ИЗ
    РегистрСведений.ВерсииПрограмм КАК РегистрВерсии
        ВНУТРЕННЕЕ СОЕДИНЕНИЕ (
            ВЫБРАТЬ
                МАКСИМУМ(ВложенныйРегистр.Период) КАК МаксПериод,
                ВложенныйРегистр.Программа КАК Программа
            ИЗ
                РегистрСведений.ВерсииПрограмм КАК ВложенныйРегистр
            ГРУППИРОВАТЬ ПО
                ВложенныйРегистр.Программа
        ) КАК ВложенныйЗапрос
        ПО РегистрВерсии.Программа = ВложенныйЗапрос.Программа
            И РегистрВерсии.Период = ВложенныйЗапрос.МаксПериод

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

Решение 2: Ограничение через параметры виртуальной таблицы

Выясним причину медленной работы некоторых списков. Часто разработчики накладывают условия фильтрации в секции ГДЕ. Это ошибка. Для оптимизации работы СрезПоследних условия по измерениям нужно передавать непосредственно в параметры виртуальной таблицы. Это заставляет SQL-сервер выполнять отбор на этапе формирования среза, а не после выборки всех данных.

Проанализируем пример правильного обращения:

РегистрСведений.ИмяРегистра.СрезПоследних(&Период, Программа = &ВыбраннаяПрограмма)

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

Решение 3: Специфика динамического списка и «Основная таблица»

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

Однако, как только вы добавляете ГРУППИРОВАТЬ ПО или сложные соединения для отсечения дублей, уникальность ключа может нарушиться. Рассмотрим подробнее настройки списка:

Практические советы по оптимизации

Чтобы ваш динамический список не «тормозил» при большом объеме данных, проанализируем ситуацию с индексами:

  1. Индексация измерений: Проверьте в конфигураторе, установлена ли галочка «Индексировать» у тех измерений, по которым вы делаете срез или соединение. Без этого поиск МАКСИМУМ(Период) заставит систему сканировать весь регистр.
  2. Минимизация вложенности: Старайтесь не злоупотреблять вложенными запросами внутри динамического списка, так как они выполняются при каждой прокрутке (скроллинге). Если данных очень много, возможно, стоит пересмотреть архитектуру и хранить «последнее состояние» в отдельном справочнике или ресурсе другого регистра.
  3. Использование Момента Времени: В запросах 1С версии 8.3 для получения самой последней записи эффективнее сравнивать записи по МоментуВремени, который включает в себя и дату, и ссылку на документ-регистратор, обеспечивая абсолютную уникальность в пределах одной секунды.

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

← На главную