В практике разработки на платформе 1С:Предприятие 8.3 часто возникает мистическая ситуация. Вы разрабатываете или модифицируете форму, содержащую динамический список. Вы вносите изменения в текст запроса списка, запускаете сеанс под пользователем, но список оказывается абсолютно пустым. При этом, если скопировать этот же запрос со всеми параметрами в Консоль запросов, он успешно возвращает нужные строки. Более того, даже программная выгрузка схемы компоновки данных динамического списка в таблицу значений показывает, что данные физически выбираются СУБД.
В этой статье мы подробно разберем, почему возникает этот эффект, проанализируем внутренние механизмы работы платформы 1С (на примере конфигурации 1С:Комплексная автоматизация 2.2 / ERP и платформы 8.3.12) и рассмотрим по шагам, как решить эту проблему.
Прежде чем приступать к исправлению кода, необходимо точно убедиться, что проблема кроется именно в визуальном отображении списка на клиенте, а не в ошибке формирования параметров запроса на сервере. Для этого применим надежный метод программной деструктуризации динамического списка. Мы перехватим исполняемую схему компоновки (СКД) динамического списка непосредственно перед выводом на экран и выгрузим результат в обычную таблицу значений.
Для этого в процедуре ПриСозданииНаСервере или ПриОткрытии перед самым завершением установим точку останова и выполним в табло или вставим в код следующий фрагмент:
Схема = Элементы.Список.ПолучитьИсполняемуюСхемуКомпоновкиДанных();
Настройки = Элементы.Список.ПолучитьИсполняемыеНастройкиКомпоновкиДанных();
КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(Схема, Настройки, , , Тип("ГенераторМакетаКомпоновкиДанныхДляКоллекцииЗначений"));
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ТЗДинамическогоСписка = ПроцессорВывода.Вывести(ПроцессорКомпоновки);
Если в полученной таблице значений ТЗДинамическогоСписка присутствуют искомые строки документов (например, документы ПоступлениеТоваровУслуг), но на форме в режиме пользователя табличное поле остается абсолютно чистым — мы имеем дело с платформенной фильтрацией или особенностями рендеринга сетки. Выясним основные причины этого поведения.
---
Это наиболее частая причина «исчезновения» строк из динамического списка при работе в типовых конфигурациях (КА, ERP, УТ).
Рассмотрим механику процесса подробнее. Когда мы открываем форму выбора документов расчетов (например, общую форму ВыборДокументаРасчетов) из родительского документа Списание безналичных денежных средств, платформа автоматически связывает реквизиты формы. В свойствах элемента формы-источника или в коде формы выбора жестко прописываются связи параметров выбора. Чаще всего накладывается автоматический отбор по организации:
Список.Отбор.Организация Равно [ЗначениеОрганизацииИзДокументаСписания]
В нашем случае в запросе динамического списка для документа ПоступлениеТоваровУслуг было добавлено условие:
И (ДанныеДокумента.Организация В (&Организация) ИЛИ ДанныеДокумента.ОрганизацияРегл В (&Организация))
Если в документе-источнике указана организация «Ромашка-Регл», а в самом документе поступления в основном реквизите Организация выбрана «Ромашка-Упр», но в реквизите ОрганизацияРегл стоит «Ромашка-Регл», то СУБД честно вернет эту запись, так как сработало условие по ИЛИ.
Однако при передаче данных на клиентский уровень динамический список видит, что в поле Организация у этой строки содержится «Ромашка-Упр». Платформа сверяет это значение с активным (и часто невидимым для разработчика в коде) отбором по организации («Ромашка-Регл») и мгновенно отсекает строку из визуального отображения. С точки зрения платформы, строка не удовлетворяет текущим интерактивным отборам списка.
Как решить проблему:
Организация возвращать то значение, по которому происходит реальное сопоставление, например, через конструкцию ВЫБОР:
ВЫБОР
КОГДА ДанныеДокумента.ОрганизацияРегл В (&Организация) ТОГДА ДанныеДокумента.ОрганизацияРегл
ИНАЧЕ ДанныеДокумента.Организация
КОНЕЦ КАК Организация
---
Если вы разрабатываете функционал под учетной записью администратора (с полными правами), а пользователи работают с ограниченными ролями, в дело вступает механизм RLS (Record Level Security). В крупных конфигурациях, таких как КА 2.2 и ERP, RLS по организациям работает на уровне платформенных шаблонов.
Шаблоны ограничений RLS в типовых решениях «заточены» строго под стандартные реквизиты объектов (поле Организация). Платформа ничего не знает о существовании вашего нового реквизита ОрганизацияРегл и не умеет автоматически давать к нему доступ, если у пользователя нет прав на значение в стандартном поле Организация.
Когда динамический список компилирует итоговый SQL-запрос к базе данных под правами обычного пользователя, платформа неявно добавляет условия RLS во все секции ГДЕ. В результате строка документа просто отсекается на уровне СУБД.
Как решить проблему:
ОрганизацияРегл, либо перевести форму выбора на работу с программно заполняемой таблицей значений вместо динамического списка, если данные должны выбираться без учета жестких ограничений по основному полю.---
В форме ВыборДокументаРасчетов используется огромный запрос, состоящий из множества секций ОБЪЕДИНИТЬ ВСЕ (выбираются заказы, поступления, накладные, договоры и т.д.). У такого динамического списка в свойствах не задана Основная таблица.
Когда свойство «Основная таблица» пустое, платформа 1С вынуждена самостоятельно определять уникальные ключевые поля для построения динамической выборки (динамического скроллинга строк в UI). Ключевым полем по умолчанию становится поле Ссылка.
Поскольку в запросе объединяются таблицы совершенно разных типов (различные документы и справочники), результирующее поле Ссылка имеет сложный составной тип. На старых релизах платформы (включая 8.3.12) существует зарегистрированная особенность работы: при совпадении определенных условий или типов платформа не может корректно сопоставить уникальный идентификатор строки составного типа и просто скрывает записи в интерфейсе.
Как решить проблему:
Ссылка принудительно установим свойство «Ключевое поле» (поставим флаг в соответствующей колонке). Это жестко укажет платформе, по какому именно полю нужно идентифицировать строки и строить кэш отображения.---
При активной разработке структура запроса динамического списка постоянно меняется (добавляются новые колонки, изменяются условия связи). Однако платформа 1С сохраняет настройки отображения формы (видимость колонок, примененные пользователем отборы, положение элементов) в системном кэше и в системных регистрах хранения настроек.
Если у пользователя сохранены старые настройки формы, они накладываются поверх нового динамического списка в момент его инициализации. Это может приводить к тому, что новые колонки или строки, подлежащие выводу по новым правилам запроса, блокируются старыми механизмами фильтрации, сохраненными в кэше.
Как решить проблему:
ВыборДокументаРасчетов./ClearCache для полной очистки локального кэша метаданных.