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

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

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

Анализ ситуации: суть проблемы

Рассмотрим классический пример, описанный в нашей задаче. В конфигурации (например, на платформе 8.3.5.x) создается форма, на которой размещен динамический список. Основной таблицей выступает Регистр Сведений (РС). В тексте произвольного запроса разработчик связывает первый регистр с двумя другими регистрами левым соединением (LEFT JOIN). При этом используются виртуальные таблицы, например, срез последних. На эти таблицы накладываются параметры:

  1. Параметр на виртуальную таблицу и измерение первого регистра.
  2. Параметр на период виртуальной таблицы второго регистра.
  3. Параметр на период виртуальной таблицы третьего регистра.

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

Причина 1: Оптимизация запросов механизмом СКД

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

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

Причина 2: Конфликт стандартных параметров периода

Проанализируем работу с виртуальными таблицами среза последних. Когда в запросе используется несколько таких таблиц, система неявно генерирует стандартный параметр &Период. Если вы пытаетесь задать собственные параметры для дат (например, дату пользователя для второго и третьего регистра), возникает внутренний конфликт СКД. Система может проигнорировать ваши пользовательские параметры дат и попытаться подставить пустой стандартный параметр &Период ко всем трем виртуальным таблицам. Срез на "пустую" дату (или конфликт дат) приводит к пустому результату.

Причина 3: Особенности работы флага "Основная таблица"

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

Решение 1: Переход от параметров к отборам (Рабочий обходной путь)

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

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

Удалите параметры из свойств виртуальных таблиц в тексте запроса динамического списка. Вместо этого устанавливайте отбор программно при открытии формы:


ЭлементОтбора = Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ВашеИзмерение");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ПравоеЗначение = НужноеЗначение;

Применение ограничений "сверху" через отбор позволяет обойти ошибку некорректного построения левого соединения в СКД.

Решение 2: Явное переименование параметров виртуальных таблиц

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

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


ВЫБРАТЬ
    Регистр1.Поле1,
    Регистр2.Поле2
ИЗ
    РегистрСведений.НашРегистр1.СрезПоследних(&ПериодРС1, ) КАК Регистр1
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НашРегистр2.СрезПоследних(&ПериодРС2, ) КАК Регистр2
        ПО Регистр1.Измерение = Регистр2.Измерение

После этого принудительно устанавливайте значения этих параметров программно перед открытием формы. Это исключит ситуацию, когда СКД затирает ваши данные пустым системным параметром &Период.

Решение 3: Отключение флага "Основная таблица"

Если запрос сложный, попробуйте снять флажок "Основная таблица" в настройках динамического списка. Список превратится в полностью произвольный запрос, и СКД перестанет пытаться навязывать свои автоматические связи ключей основной таблицы к левым соединениям. Зачастую после снятия этого флага параметры начинают отрабатывать корректно.

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

Решение 4: Влияние RLS и обновление платформы

Рассмотрим еще два важных фактора. Во-первых, пустой список при заполненных параметрах часто является следствием работы ограничения прав доступа (RLS). Если хотя бы на один из присоединяемых регистров настроены права на уровне записей, 1С неявно добавляет условия RLS в запрос. При левом соединении конфликт параметров RLS и параметров виртуальных таблиц может отсечь все строки. Убедитесь, что проблема воспроизводится под полными правами. Если под полными правами список заполняется, значит проблема в логике RLS.

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

← На главную