Как добавить данные из регистра сведений в форму подбора номенклатуры в 1С:Бухгалтерия 3.0?

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

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

Сложность заключается в том, что нужные данные хранятся не в реквизитах самого справочника номенклатуры, а в отдельном регистре сведений (в нашем случае — СведенияОбАлкогольнойПродукции). Рассмотрим несколько вариантов решения этой задачи, проанализируем их плюсы и минусы, а также выясним причины потенциальных ошибок.

Способ 1: Изменение текста запроса динамического списка

Самый простой и очевидный путь — модифицировать запрос, который поставляет данные для формы. Формы подбора и выбора построены на основе динамических списков.

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

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

Пример запроса, который добавляет поле алкогольного кода в выборку:


ВЫБРАТЬ
    СправочникНоменклатура.Ссылка КАК Ссылка,
    СправочникНоменклатура.Наименование КАК Наименование,
    СправочникНоменклатура.Артикул КАК Артикул,
    СведенияОбАлкогольнойПродукции.КодВида169 КАК КодВида169
ИЗ
    Справочник.Номенклатура КАК СправочникНоменклатура
        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.СведенияОбАлкогольнойПродукции КАК СведенияОбАлкогольнойПродукции
        ПО СправочникНоменклатура.Ссылка = СведенияОбАлкогольнойПродукции.Номенклатура

После добавления поля КодВида169 в запрос, мы можем просто вытянуть его на элементы формы в дерево элементов и оно отобразится у пользователей. Однако у этого метода в условиях конфигурации БП 3.0 есть подводные камни.

Способ 2: Безопасная модификация запроса (СхемаЗапроса)

Если мы просто заменим функцию ТекстЗапросаДинамическогоСписка в модуле формы через расширение (с помощью аннотации &Вместо), мы рискуем. При первом же обновлении конфигурации, когда фирма 1С добавит новые поля или изменит логику типового запроса, наша жестко прописанная замена сломает форму подбора.

Разберем более грамотный и безопасный подход — использование объекта СхемаЗапроса. Мы можем перехватить формирование запроса списка при создании формы (через &После("ПриСозданииНаСервере")) и аккуратно добавить нужное нам соединение программно.


&НаСервере
Процедура Расш1_ПриСозданииНаСервереПосле(Отказ, СтандартнаяОбработка)
    
    Схема = Новый СхемаЗапроса;
    Схема.УстановитьТекстЗапроса(Список.Параметры.ТекстЗапроса); // или Список.ПроизвольныйЗапрос = Истина;
    
    // Получаем первый пакет запроса
    Пакет = Схема.ПакетЗапросов[0];
    
    // Добавляем источник (наш регистр сведений)
    ИсточникРегистр = Пакет.Источники.Добавить("РегистрСведений.СведенияОбАлкогольнойПродукции", "СведенияАлкоголь");
    
    // Настраиваем левое соединение
    ИсточникНоменклатура = Пакет.Источники[0]; // Предполагаем, что справочник номенклатуры первый
    УсловиеСоединения = "ИсточникНоменклатура.Ссылка = СведенияАлкоголь.Номенклатура";
    ИсточникРегистр.Соединения.Добавить(ИсточникНоменклатура, УсловиеСоединения, ТипСоединенияСхемыЗапроса.Левое);
    
    // Добавляем поле в выборку
    Пакет.Колонки.Добавить("СведенияАлкоголь.КодВида169", "КодВида169");
    
    // Обновляем текст запроса списка
    Список.ТекстЗапроса = Схема.ПолучитьТекстЗапроса();
    
КонецПроцедуры

Используя данный метод, мы сохраняем всю типовую логику отбора 1С, добавляя лишь необходимую нам "примесь".

Способ 3: Оптимизация через ПриПолученииДанныхНаСервере

Форма подбора номенклатуры — один из самых высоконагруженных интерфейсов. Добавление конструкций ЛЕВОЕ СОЕДИНЕНИЕ с таблицами регистров сведений непосредственно в динамический список может существенно замедлить скроллинг и отклик формы. Если пользователю не требуется сложная фильтрация или сортировка именно по этому полю алкогольного кода, лучше использовать другой механизм.

Проанализируем альтернативный вариант вывода данных. Мы можем вообще не трогать запрос списка, а выводить данные "на лету" только для тех строк, которые в данный момент отображаются на экране. Для этого используется событие ПриПолученииДанныхНаСервере.


&НаСервереБезКонтекста
Процедура СписокПриПолученииДанныхНаСервере(ИмяЭлемента, Настройки, Строки)
    
    // Собираем массив ссылок текущих видимых строк
    МассивНоменклатуры = Новый Массив;
    Для Каждого КлючИЗначение Из Строки Цикл
        МассивНоменклатуры.Добавить(КлючИЗначение.Ключ);
    КонецЦикла;
    
    // Пакетным запросом получаем данные из регистра только для видимых товаров
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |   Сведения.Номенклатура КАК Номенклатура,
        |   Сведения.КодВида169 КАК КодВида169
        |ИЗ
        |   РегистрСведений.СведенияОбАлкогольнойПродукции КАК Сведения
        |ГДЕ
        |   Сведения.Номенклатура В(&МассивНоменклатуры)";
        
    Запрос.УстановитьПараметр("МассивНоменклатуры", МассивНоменклатуры);
    Выборка = Запрос.Выполнить().Выбрать();
    
    // Заполняем данные в строках
    Пока Выборка.Следующий() Цикл
        СтрокаСписка = Строки[Выборка.Номенклатура];
        СтрокаСписка.Данные["КодВида169"] = Выборка.КодВида169;
    КонецЦикла;
    
КонецПроцедуры

В этом случае колонка КодВида169 просто добавляется на форму как реквизит, и мы заполняем ее программно. Это работает невероятно быстро, так как запрос выполняется максимум для 30-50 строк, которые видит пользователь.

Важные технические нюансы

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

  1. Настройка поиска по новому реквизиту. Если вы хотите, чтобы пользователь мог искать товары по новому полю в строке поиска, простого вывода колонки недостаточно. Необходимо убедиться, что новое поле добавлено в свойства дополнения строки поиска списка. Если запрос формировался программно, проверьте настройки компоновки данных.
  2. Очистка пользовательских настроек (кэш СКД). Самая частая проблема, с которой сталкиваются после добавления колонки: у разработчика всё работает, а у пользователя система выдает ошибку "Поле не найдено: КодВида169". Это происходит из-за того, что система компоновки данных закэшировала старый вариант настроек списка. Для решения проблемы нужно очистить пользовательские настройки конкретной формы через стандартную обработку или выполнить метод ХранилищеСистемныхНастроек.Удалить().
  3. Специфика обработки "ПодборНоменклатуры". В БП 3.0 форма подбора очень динамична. При смене режима (например, нажатии кнопки "Только с остатками", переключении видов иерархии или смене типа цен) типовой код может заново перестраивать текст запроса. Обязательно протестируйте ваше решение при переключении всех фильтров в форме, чтобы убедиться, что ваше левое соединение или поле не исчезает при действиях пользователя.
← На главную