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

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

В практике разработки на платформе 1С:Предприятие 8.3 часто возникает мистическая ситуация. Вы разрабатываете или модифицируете форму, содержащую динамический список. Вы вносите изменения в текст запроса списка, запускаете сеанс под пользователем, но список оказывается абсолютно пустым. При этом, если скопировать этот же запрос со всеми параметрами в Консоль запросов, он успешно возвращает нужные строки. Более того, даже программная выгрузка схемы компоновки данных динамического списка в таблицу значений показывает, что данные физически выбираются СУБД.

В этой статье мы подробно разберем, почему возникает этот эффект, проанализируем внутренние механизмы работы платформы 1С (на примере конфигурации 1С:Комплексная автоматизация 2.2 / ERP и платформы 8.3.12) и рассмотрим по шагам, как решить эту проблему.

Шаг 1. Первичная диагностика: Программная выгрузка схемы динамического списка

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

Для этого в процедуре ПриСозданииНаСервере или ПриОткрытии перед самым завершением установим точку останова и выполним в табло или вставим в код следующий фрагмент:


Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();

КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ТЗДинамическогоСписка = ПроцессорВывода.Вывести(ПроцессорКомпоновки);

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

---

Причина 1. Конфликт неявных отборов и свойств «Связи параметров выбора»

Это наиболее частая причина «исчезновения» строк из динамического списка при работе в типовых конфигурациях (КА, ERP, УТ).

Рассмотрим механику процесса подробнее. Когда мы открываем форму выбора документов расчетов (например, общую форму ВыборДокументаРасчетов) из родительского документа Списание безналичных денежных средств, платформа автоматически связывает реквизиты формы. В свойствах элемента формы-источника или в коде формы выбора жестко прописываются связи параметров выбора. Чаще всего накладывается автоматический отбор по организации:

Список.Отбор.Организация Равно [ЗначениеОрганизацииИзДокументаСписания]

В нашем случае в запросе динамического списка для документа ПоступлениеТоваровУслуг было добавлено условие:


И (ДанныеДокумента.Организация В (&Организация) ИЛИ ДанныеДокумента.ОрганизацияРегл В (&Организация))

Если в документе-источнике указана организация «Ромашка-Регл», а в самом документе поступления в основном реквизите Организация выбрана «Ромашка-Упр», но в реквизите ОрганизацияРегл стоит «Ромашка-Регл», то СУБД честно вернет эту запись, так как сработало условие по ИЛИ.

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

Как решить проблему:

  1. Проанализируем свойства поля ввода на форме-источнике (откуда открывается выбор). Проверим свойство «Связи параметров выбора». Если там настроена жесткая связь по организации, ее необходимо скорректировать или очистить программно при открытии формы.
  2. В запросе динамического списка для проблемного документа в качестве выбираемого поля Организация возвращать то значение, по которому происходит реальное сопоставление, например, через конструкцию ВЫБОР:

ВЫБОР 
    КОГДА ДанныеДокумента.ОрганизацияРегл В (&Организация) ТОГДА ДанныеДокумента.ОрганизацияРегл 
    ИНАЧЕ ДанныеДокумента.Организация 
КОНЕЦ КАК Организация

---

Причина 2. Влияние механизма RLS (Ограничение доступа на уровне записей)

Если вы разрабатываете функционал под учетной записью администратора (с полными правами), а пользователи работают с ограниченными ролями, в дело вступает механизм RLS (Record Level Security). В крупных конфигурациях, таких как КА 2.2 и ERP, RLS по организациям работает на уровне платформенных шаблонов.

Шаблоны ограничений RLS в типовых решениях «заточены» строго под стандартные реквизиты объектов (поле Организация). Платформа ничего не знает о существовании вашего нового реквизита ОрганизацияРегл и не умеет автоматически давать к нему доступ, если у пользователя нет прав на значение в стандартном поле Организация.

Когда динамический список компилирует итоговый SQL-запрос к базе данных под правами обычного пользователя, платформа неявно добавляет условия RLS во все секции ГДЕ. В результате строка документа просто отсекается на уровне СУБД.

Как решить проблему:

  1. Выполним проверку под пользователем с абсолютно полными правами. Если под полными правами документы отображаются в списке корректно, проблема однозначно в RLS.
  2. Необходимо внести изменения в роли пользователей, добавив правила доступа с учетом нового реквизита ОрганизацияРегл, либо перевести форму выбора на работу с программно заполняемой таблицей значений вместо динамического списка, если данные должны выбираться без учета жестких ограничений по основному полю.

---

Причина 3. Отсутствие основной таблицы в динамическом списке при использовании сложных объединений (UNION)

В форме ВыборДокументаРасчетов используется огромный запрос, состоящий из множества секций ОБЪЕДИНИТЬ ВСЕ (выбираются заказы, поступления, накладные, договоры и т.д.). У такого динамического списка в свойствах не задана Основная таблица.

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

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

Как решить проблему:

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

---

Причина 4. Кэширование пользовательских настроек формы

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

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

Как решить проблему:

← На главную