Часто в процессе адаптации типовой конфигурации возникает необходимость расширить стандартные формы поиска и подбора номенклатуры. Разберем типичную задачу: нам нужно вывести дополнительную информацию о товарах (например, код вида алкогольной продукции) в таблицу выбора формы Обработка.ПодборНоменклатуры или Справочник.Номенклатура.ФормаВыбора в конфигурации 1С:Бухгалтерия предприятия 3.0.
Сложность заключается в том, что нужные данные хранятся не в реквизитах самого справочника номенклатуры, а в отдельном регистре сведений (в нашем случае — СведенияОбАлкогольнойПродукции). Рассмотрим несколько вариантов решения этой задачи, проанализируем их плюсы и минусы, а также выясним причины потенциальных ошибок.
Самый простой и очевидный путь — модифицировать запрос, который поставляет данные для формы. Формы подбора и выбора построены на основе динамических списков.
Рассмотрим по шагам, как добавить нужные поля в динамический список:
ФормаВыбора справочника Номенклатура).Список или СписокНоменклатуры).Пример запроса, который добавляет поле алкогольного кода в выборку:
ВЫБРАТЬ
СправочникНоменклатура.Ссылка КАК Ссылка,
СправочникНоменклатура.Наименование КАК Наименование,
СправочникНоменклатура.Артикул КАК Артикул,
СведенияОбАлкогольнойПродукции.КодВида169 КАК КодВида169
ИЗ
Справочник.Номенклатура КАК СправочникНоменклатура
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СведенияОбАлкогольнойПродукции КАК СведенияОбАлкогольнойПродукции
ПО СправочникНоменклатура.Ссылка = СведенияОбАлкогольнойПродукции.Номенклатура
После добавления поля КодВида169 в запрос, мы можем просто вытянуть его на элементы формы в дерево элементов и оно отобразится у пользователей. Однако у этого метода в условиях конфигурации БП 3.0 есть подводные камни.
Если мы просто заменим функцию ТекстЗапросаДинамическогоСписка в модуле формы через расширение (с помощью аннотации &Вместо), мы рискуем. При первом же обновлении конфигурации, когда фирма 1С добавит новые поля или изменит логику типового запроса, наша жестко прописанная замена сломает форму подбора.
Разберем более грамотный и безопасный подход — использование объекта СхемаЗапроса. Мы можем перехватить формирование запроса списка при создании формы (через &После("ПриСозданииНаСервере")) и аккуратно добавить нужное нам соединение программно.
&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
Схема = Новый СхемаЗапроса;
Схема.УстановитьТекстЗапроса(Список.Параметры.ТекстЗапроса); // или Список.ПроизвольныйЗапрос = Истина;
// Получаем первый пакет запроса
Пакет = Схема.ПакетЗапросов[0];
// Добавляем источник (наш регистр сведений)
ИсточникРегистр = Пакет.Источники.Добавить("РегистрСведений.СведенияОбАлкогольнойПродукции", "СведенияАлкоголь");
// Настраиваем левое соединение
ИсточникНоменклатура = Пакет.Источники[0]; // Предполагаем, что справочник номенклатуры первый
УсловиеСоединения = "ИсточникНоменклатура.Ссылка = СведенияАлкоголь.Номенклатура";
ИсточникРегистр.Соединения.Добавить(ИсточникНоменклатура, УсловиеСоединения, ТипСоединенияСхемыЗапроса.Левое);
// Добавляем поле в выборку
Пакет.Колонки.Добавить("СведенияАлкоголь.КодВида169", "КодВида169");
// Обновляем текст запроса списка
Список.ТекстЗапроса = Схема.ПолучитьТекстЗапроса();
КонецПроцедуры
Используя данный метод, мы сохраняем всю типовую логику отбора 1С, добавляя лишь необходимую нам "примесь".
Форма подбора номенклатуры — один из самых высоконагруженных интерфейсов. Добавление конструкций ЛЕВОЕ СОЕДИНЕНИЕ с таблицами регистров сведений непосредственно в динамический список может существенно замедлить скроллинг и отклик формы. Если пользователю не требуется сложная фильтрация или сортировка именно по этому полю алкогольного кода, лучше использовать другой механизм.
Проанализируем альтернативный вариант вывода данных. Мы можем вообще не трогать запрос списка, а выводить данные "на лету" только для тех строк, которые в данный момент отображаются на экране. Для этого используется событие ПриПолученииДанныхНаСервере.
&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
// Собираем массив ссылок текущих видимых строк
МассивНоменклатуры = Новый Массив;
Для Каждого КлючИЗначение Из Строки Цикл
МассивНоменклатуры.Добавить(КлючИЗначение.Ключ);
КонецЦикла;
// Пакетным запросом получаем данные из регистра только для видимых товаров
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Сведения.Номенклатура КАК Номенклатура,
| Сведения.КодВида169 КАК КодВида169
|ИЗ
| РегистрСведений.СведенияОбАлкогольнойПродукции КАК Сведения
|ГДЕ
| Сведения.Номенклатура В(&МассивНоменклатуры)";
Запрос.УстановитьПараметр("МассивНоменклатуры", МассивНоменклатуры);
Выборка = Запрос.Выполнить().Выбрать();
// Заполняем данные в строках
Пока Выборка.Следующий() Цикл
СтрокаСписка = Строки[Выборка.Номенклатура];
СтрокаСписка.Данные["КодВида169"] = Выборка.КодВида169;
КонецЦикла;
КонецПроцедуры
В этом случае колонка КодВида169 просто добавляется на форму как реквизит, и мы заполняем ее программно. Это работает невероятно быстро, так как запрос выполняется максимум для 30-50 строк, которые видит пользователь.
При доработке динамических списков необходимо учитывать несколько важных моментов:
ХранилищеСистемныхНастроек.Удалить().