Как в справочнике номенклатуры отобразить только группы с остатками

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

В типовых конфигурациях на обычных формах (например, УТ 10.3) справочник номенклатуры часто разрастается до огромных размеров. Пользователям бывает неудобно ориентироваться в десятках пустых папок, в которых на данный момент нет товара. Стандартный механизм отбора в СправочникСписок по остаткам работает прямолинейно: он скрывает товары без остатков, но оставляет видимыми все группы, что создает визуальный шум.

В этой статье мы разберем, как реализовать механизм, который оставит в списке только «полезные» ветки иерархии. Проанализируем ситуацию и рассмотрим несколько подходов: от простых запросов до изменения структуры формы.

Проблема иерархического отбора в обычных формах

Когда мы устанавливаем отбор типа Ссылка В Списке, платформа 1С в режиме обычных форм ведет себя специфически при включенном иерархическом просмотре. Если в список отбора включить только товары, имеющие остаток, но не включить их родительские группы, то в режиме дерева эти товары могут просто исчезнуть, так как их «родители» не прошли фильтр. Если же оставить иерархию включенной без фильтрации самих групп, мы увидим пустые папки. Следовательно, наша задача — получить список всех товаров с остатками и всех их вышестоящих родителей, а затем применить этот список в качестве отбора.

Способ 1. Использование запроса с итогами по иерархии

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

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


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|   ТоварыНаСкладахОстатки.Номенклатура КАК Ссылка,
|   ТоварыНаСкладахОстатки.КоличествоОстаток КАК Количество
|ИЗ
|   РегистрНакопления.ТоварыНаСкладах.Остатки(&Период, ) КАК ТоварыНаСкладахОстатки
|ИТОГИ СУММА(Количество) ПО
|   Ссылка ИЕРАРХИЯ";

Запрос.УстановитьПараметр("Период", ТекущаяДата());

РезультатЗапроса = Запрос.Выполнить();
ДеревоРезультата = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);

// Теперь соберем все ссылки из дерева в массив
СписокРазрешенныхСсылок = Новый СписокЗначений;

Для каждого СтрокаИзДерева Из ДеревоРезультата.Строки Цикл
    ДобавитьСсылкуРекурсивно(СтрокаИзДерева, СписокРазрешенныхСсылок);
КонецЦикла;

В этом примере функция ДобавитьСсылкуРекурсивно должна обходить дерево и добавлять ссылки в список. Использование ключевого слова ИЕРАРХИЯ в блоке ИТОГИ заставляет систему автоматически вычислить всех родителей для каждой найденной номенклатуры с остатком. Это избавляет нас от медленных циклов Пока ЗначениеЗаполнено(Родитель) в коде 1С, перекладывая работу на СУБД.

Способ 2. Интерфейсное разделение (Дерево групп + Список товаров)

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

  1. Изменение формы: Разделим форму справочника на две части. Слева разместим элемент управления ДеревоЗначений, а справа — стандартное ТабличноеПоле со списком номенклатуры.
  2. Заполнение дерева: При открытии формы заполним левое дерево только теми группами, в которых есть остатки (используя запрос из Способа 1, но ограничив выборку только папками).
  3. Связь элементов: При выборе строки в дереве групп будем устанавливать отбор в правом списке товаров по текущему родителю и флагу наличия остатка.

Посмотрим на пример заполнения дерева групп:


// Запрос выбирает только группы (ЭтоГруппа = Истина), имеющие остатки в иерархии
Запрос.Текст = 
"ВЫБРАТЬ РАЗЛИЧНЫЕ
|   Номенклатура.Ссылка КАК Группа
|ИЗ
|   Справочник.Номенклатура КАК Номенклатура
|ГДЕ
|   Номенклатура.ЭтоГруппа
|   И Номенклатура.Ссылка В ИЕРАРХИИ (
|       ВЫБРАТЬ РАЗЛИЧНЫЕ Номенклатура КАК Ссылка
|       ИЗ РегистрНакопления.ТоварыНаСкладах.Остатки
|   )";

Этот метод визуально скрывает пустые папки, так как они просто не попадают в левую панель навигации. В основном списке товаров справа (в СправочникСписок) при этом нужно отключить иерархический просмотр, чтобы видеть плоский список товаров выбранной категории.

Способ 3. Оптимизация через "Теневые реквизиты" или кэширование

Выясним причину, по которой первые два способа могут тормозить на слабых серверах — это расчет остатков в реальном времени при каждом открытии справочника. Если оперативность данных в 1-2 минуты не критична, можно использовать механизм кэширования.

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

СправочникСписок.Отбор.ЕстьОстаток.Установить(Истина);

Это самый быстрый способ с точки зрения интерфейса, так как 1С работает с заранее подготовленными данными и не обращается к таблицам итогов регистров накопления при каждом обновлении экрана.

Важные замечания по реализации

При реализации любого из способов обратите внимание на следующие моменты:

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

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

← На главную