При работе с конфигурациями на базе современных версий 1С:ERP, КА 2 или УТ 11 многие разработчики сталкиваются с ситуацией, когда стандартное изменение запроса динамического списка в конфигураторе не приносит желаемого результата. Особенно часто это проявляется в обработке подбора товаров. В этой статье мы подробно разберем, почему «простой» метод не работает и как правильно внедрить свои колонки в механизм подбора.
Рассмотрим ситуацию, с которой столкнулся автор темы. При попытке добавить ЛЕВОЕ СОЕДИНЕНИЕ с регистром ЦеныНоменклатуры.СрезПоследних напрямую в динамический список СписокНоменклатуры в обработке подбора, новые поля не появляются в пользовательском режиме. Проанализируем, почему это происходит.
Дело в том, что в типовых решениях (УТ 11, ERP 2) механизм подбора товаров реализован максимально гибко. Текст запроса, который вы видите в конструкторе динамического списка на форме, является лишь заготовкой (шаблоном). При инициализации формы система выполняет следующие действия:
ПриСозданииНаСервере.ПодборТоваровСервер).Именно поэтому любые правки, внесенные «руками» в визуальном редакторе конфигуратора, бесследно исчезают в момент запуска программы.
Разберем, где именно происходит «магия» сборки запроса. Нам необходимо обратить внимание на модуль формы обработки ПодборТоваровТовары (или аналогичной в вашей версии). Чаще всего ключевая логика скрыта в вызовах процедур, подготавливающих структуру поиска.
Проанализируем пример кода, который обычно отвечает за установку параметров и структуры запроса в динамических списках такого типа:
// Пример логики, которая может перекрывать ваш запрос
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Вызов типового механизма инициализации подбора
ПодборТоваровЛогикаСервер.ПриСозданииНаСервере(ЭтаФорма, Параметры);
// Здесь система может переопределить ТекстЗапроса
ТекстЗапроса = СписокНоменклатуры.ТекстЗапроса;
// ... динамическое добавление условий ГДЕ, соединений и полей ...
СписокНоменклатуры.ТекстЗапроса = ТекстЗапроса;
КонецПроцедуры
Чтобы наши колонки (например, Закупочная цена) отобразились, нам нужно внедрить изменения именно в этот процесс сборки.
Наиболее правильным и безопасным методом будет создание расширения. Нам нужно перехватить процедуру, которая отвечает за формирование текста запроса для списка номенклатуры. В УТ 11 это часто делается в общем модуле ПодборТоваровСервер или непосредственно в модуле формы подбора.
Рассмотрим пример добавления поля цены через расширение метода ПодготовитьЗапросДляСпискаНоменклатуры (название может варьироваться в зависимости от релиза):
&После("ДополнитьТекстЗапросаДляСпискаНоменклатуры")
Процедура Расш_ДополнитьТекстЗапросаДляСпискаНоменклатуры(ТекстЗапроса, ПараметрыПодбора)
// Добавляем поле в блок ВЫБРАТЬ
ТекстЗапроса = СтрЗаменить(ТекстЗапроса,
"СправочникНоменклатура.Ссылка КАК Ссылка,",
"СправочникНоменклатура.Ссылка КАК Ссылка,
| ЕСТЬNULL(ЦеныЗакупки.Цена, 0) КАК ЦенаЗакупка,");
// Добавляем соединение с регистром сведений
ТекстЗапроса = ТекстЗапроса + "
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЦеныНоменклатуры.СрезПоследних(&Период, ВидЦены = &ВидЦеныЗакупка) КАК ЦеныЗакупки
| ПО ЦеныЗакупки.Номенклатура = СправочникНоменклатура.Ссылка";
КонецПроцедуры
Важный момент: Мы используем &ВидЦеныЗакупка как отдельный параметр, чтобы не конфликтовать со стандартным параметром цены продажи, который уже может использоваться системой.
После того как мы изменили текст запроса, нам нужно передать в него значение параметра &ВидЦеныЗакупка. Посмотрим, как это сделать в модуле формы подбора:
&НаСервере
Процедура УстановитьПараметрыЗапросаЦен()
// Получаем нужную ссылку на вид цены (например, из константы или настройки)
НужныйВидЦены = ПоводкиСервер.ПолучитьВидЦеныЗакупки();
// Устанавливаем параметр в динамический список
СписокНоменклатуры.Параметры.УстановитьЗначениеПараметра("ВидЦеныЗакупка", НужныйВидЦены);
СписокНоменклатуры.Параметры.УстановитьЗначениеПараметра("Период", ТекущаяДата());
КонецПроцедуры
Эту процедуру следует вызывать в ПриСозданииНаСервере после того, как основной механизм подбора закончил свою работу.
Даже если поле появилось в запросе, оно не станет видимым само по себе, если его нет в списке элементов формы. Разберем два пути:
СписокНоменклатуры. В свойстве ПутьКДанным укажите СписокНоменклатуры.ЦенаЗакупка.
&НаСервере
Процедура ДобавитьКолонкуЦеныНаФорму()
НоваяКолонка = Элементы.Добавить("ЦенаЗакупочная", Тип("ПолеФормы"), Элементы.СписокНоменклатуры);
НоваяКолонка.Вид = ВидПоляФормы.ПолеВвода;
НоваяКолонка.ПутьКДанным = "СписокНоменклатуры.ЦенаЗакупка";
НоваяКолонка.Заголовок = "Цена закупки";
КонецПроцедуры
При реализации данного функционала следует учитывать несколько критических факторов:
Производительность: Прямое соединение (LEFT JOIN) с виртуальной таблицей СрезПоследних внутри динамического списка может значительно замедлить работу, если справочник номенклатуры насчитывает десятки тысяч позиций. Система будет выполнять этот тяжелый запрос при каждом скроллинге или поиске.
Дублирование строк: Если в регистре цен по какой-то причине окажется несколько записей на одну дату (например, разные характеристики, а соединение идет только по номенклатуре), товар в списке подбора начнет двоиться или троиться. Всегда проверяйте условия связи в ПО.
Контекст подбора: Помните, что подбор может открываться для разных документов (Реализация, Заказ, Ввод остатков). Проанализируем ситуацию: нужна ли закупочная цена в подборе для реализации? Если нет, добавьте проверку Параметры.ИмяОбъекта перед модификацией запроса, чтобы не перегружать интерфейс лишними данными там, где они не требуются.
Таким образом, для успешного вывода колонок в подборе УТ 11.4 необходимо отказаться от правок в визуальном редакторе и перейти к программному управлению текстом запроса динамического списка через механизм расширений.