При разработке расширений конфигурации разработчики часто сталкиваются с ситуацией, когда запрос к регистру бухгалтерии успешно отрабатывает в консоли или программном коде, но вызывает ошибку проверки метаданных при попытке использовать его в качестве произвольного запроса ДинамическийСписок. Разберем по шагам, почему возникает эта проблема, какие объекты конфигурации необходимо заимствовать в расширение и как правильно оптимизировать запрос к виртуальной таблице остатков.
Рассмотрим механизм работы расширений в платформе 1С:Предприятие. В программном коде объект Запрос исполняется в контексте объединенных метаданных (основная конфигурация плюс расширение). Поэтому на этапе выполнения сервер видит все типы данных, даже если они не добавлены в расширение.
Однако для динамического списка действуют более жесткие правила:
Субконто1, Субконто2, Субконто3 в регистре бухгалтерии имеют составной тип, определяемый планом видов характеристик (например, ПланВидовХарактеристик.ВидыСубконтоХозрасчетные). Если в расширение заимствован только регистр бухгалтерии без связанных типов и ПВХ, механизм динамического списка не может построить дерево колонок и выдает ошибку.Проанализируем минимально необходимый состав объектов для работы динамического списка с регистром бухгалтерии:
РегистрБухгалтерии.Хозрасчетный).Справочник.Номенклатура, Справочник.Склады, Справочник.Организации).Посмотрим на частую ошибку при написании запроса к субконто: использование разыменования через точку Субконто1.Ссылка и наложение условий в секции ГДЕ. Такой подход заставляет СУБД соединять таблицу движений со всеми таблицами типов составного субконто, что приводит к резкому падению производительности.
Разберем неоптимальный вариант запроса:
ВЫБРАТЬ
ХозрасчетныйОстатки.Субконто1.Ссылка КАК Номенклатура,
ХозрасчетныйОстатки.Субконто2.Ссылка КАК Склад,
ЕСТЬNULL(ХозрасчетныйОстатки.КоличествоОстаток, 0) КАК Количество
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(&Дата, , , ) КАК ХозрасчетныйОстатки
ГДЕ
ХозрасчетныйОстатки.Субконто1.Ссылка ССЫЛКА Справочник.Номенклатура
И ХозрасчетныйОстатки.Субконто2.Ссылка ССЫЛКА Справочник.Склады
И ХозрасчетныйОстатки.Субконто1.Ссылка = &Номенклатура
Теперь рассмотрим правильный и быстрый вариант запроса. Для максимальной производительности применим явное приведение типов через оператор ВЫРАЗИТЬ и перенесем все условия в параметры виртуальной таблицы:
ВЫБРАТЬ
ВЫРАЗИТЬ(ХозрасчетныйОстатки.Субконто1 КАК Справочник.Номенклатура) КАК Номенклатура,
ВЫРАЗИТЬ(ХозрасчетныйОстатки.Субконто2 КАК Справочник.Склады) КАК Склад,
СУММА(ЕСТЬNULL(ХозрасчетныйОстатки.КоличествоОстаток, 0)) КАК Количество
ИЗ
РегистрБухгалтерии.Хозрасчетный.Остатки(
&Дата,
Счет = &Счет,
,
Субконто1 = &Номенклатура
) КАК ХозрасчетныйОстатки
СГРУППИРОВАТЬ ПО
ВЫРАЗИТЬ(ХозрасчетныйОстатки.Субконто1 КАК Справочник.Номенклатура),
ВЫРАЗИТЬ(ХозрасчетныйОстатки.Субконто2 КАК Справочник.Склады)
Разберем ключевые правила оптимизации:
СубконтоN само по себе уже является ссылкой. Конструкция Субконто1.Ссылка порождает лишнее неявное левое соединение в SQL.ГДЕ. Это отсекает лишние данные до расчета итогов.Рассмотрим альтернативный архитектурный подход. Запросы к виртуальным таблицам остатков внутри динамических списков могут создавать значительную нагрузку на СУБД из-за внутренних механизмов постраничной выборки платформы.
Если требуется отображать остатки по текущей позиции номенклатуры на форме, более надежным решением является отказ от динамического списка в пользу обычной Таблицы значений на форме:
ТаблицаОстатков с типом ТаблицаЗначений и колонками Склад, Количество.ПриСозданииНаСервере или при смене текущей строки выполняем обычный программный запрос или используем метод РегистрыБухгалтерии.Хозрасчетный.Остатки().ЗначениеВРеквизитФормы().Такой подход полностью снимает ограничения валидации метаданных расширения, так как запрос исполняется программно и не требует добавления связанных объектов конфигуратора в состав расширения.