Как в динамическом списке через расширение конфигурации получить остатки по субконто?

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

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

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

В чем причина ошибки в расширении конфигурации

Рассмотрим, как устроен механизм работы с бухгалтерскими регистрами в контексте расширений. Таблица РегистрБухгалтерии.Хозрасчетный.Остатки формирует виртуальные поля Субконто1, Субконто2 и далее динамически, основываясь на настройках плана счетов, максимальном количестве субконто и связанных планах видов характеристик.

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

Решение 1. Программная установка текста запроса динамического списка

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

Выполним следующие шаги:

  1. Добавим необходимую форму списка справочника Номенклатура в расширение конфигурации.
  2. Добавим в форму новую колонку (например, ОстатокНаСчете10) с типом Число, путь к данным которой свяжем с новым полем динамического списка.
  3. Перейдем в модуль формы и создадим обработчик события ПриСозданииНаСервере с директивой &Вместо или &После.
  4. В коде назначим свойству Список.ТекстЗапроса строку с нашим запросом соединения, а также передадим необходимые параметры.

Посмотрим на пример реализации в коде формы расширения:


&НаСервере
Процедура Расш_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    
    // Получаем текущий текст запроса или формируем новый
    ТекстЗапросаСписка = 
        "ВЫБРАТЬ
        |    СправочникНоменклатура.Ссылка КАК Ссылка,
        |    СправочникНоменклатура.ПометкаУдаления КАК ПометкаУдаления,
        |    СправочникНоменклатура.Код КАК Код,
        |    СправочникНоменклатура.Наименование КАК Наименование,
        |    СправочникНоменклатура.Артикул КАК Артикул,
        |    ЕСТЬNULL(Остатки10.КоличествоОстатокДт, 0) КАК Кол10
        |ИЗ
        |    Справочник.Номенклатура КАК СправочникНоменклатура
        |    ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(
        |        &ПериодОстатков,
        |        Счет В ИЕРАРХИИ (&СчетаМатериалов),
        |        ,
        |    ) КАК Остатки10
        |    ПО СправочникНоменклатура.Ссылка = Остатки10.Субконто1";
    
    Список.ТекстЗапроса = ТекстЗапросаСписка;
    
    // Устанавливаем параметры динамического списка
    Список.Параметры.УстановитьЗначениеПараметра("ПериодОстатков", ТекущаяДатаСеанса());
    Список.Параметры.УстановитьЗначениеПараметра("СчетаМатериалов", ПланыСчетов.Хозрасчетный.Материалы);
    
КонецПроцедуры

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

Решение 2. Использование параметров субконто в виртуальной таблице

Рассмотрим альтернативный способ написания запроса, который позволяет избежать жесткой привязки к нумерованному полю Субконто1. Виртуальная таблица остатков принимает третьим параметром массив или фиксированный список видов субконто.

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


ВЫБРАТЬ
    СпрНоменклатура.Ссылка КАК Ссылка,
    ЕСТЬNULL(ТаблицаОстатков.КоличествоОстатокДт, 0) КАК Остаток
ИЗ
    Справочник.Номенклатура КАК СпрНоменклатура
    ЛЕВОЕ СОЕДИНЕНИЕ РегистрБухгалтерии.Хозрасчетный.Остатки(
        &Период,
        Счет В ИЕРАРХИИ (&СчетУчета),
        &ВидыСубконто,
    ) КАК ТаблицаОстатков
    ПО СпрНоменклатура.Ссылка = ТаблицаОстатков.Субконто

В коде модуля формы в параметр &ВидыСубконто передается массив, содержащий элемент ПланыВидовХарактеристик.ВидыСубконтоХозрасчетные.Номенклатура.

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

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

Разберем более производительные альтернативы реализации этой задачи:

  1. Обработчик ПриПолученииДанныхНаСервере (доступен начиная с платформы 8.3.10): самый эффективный путь отображения расчетных данных. Текст динамического списка не меняется. В обработчике события мы получаем массив только тех ссылок номенклатуры, которые в данный момент реально отображаются на экране пользователя (через коллекцию ключей), выполняем быстрый точечный запрос остатков только по этим позициям и заполняем данные в добавленной колонке.
  2. Отдельная панель сведений: вывод информации об остатках не в каждую строку таблицы, а в отдельную информационную панель формы при активизации текущей строки. Запрос остатков по одной позиции выполняется мгновенно и не замедляет общую работу со списком.
← На главную