Как в 1С 7.7 настроить подбор материалов с остатком больше нуля

Программист 1С v7.7 1C:Бухгалтерия Бухгалтерский учет IT и автоматизация бизнеса
← На главную

При оформлении документов списания, таких как Требование-накладная в конфигурации 1С:Бухгалтерский учет 7.7, часто возникает необходимость открывать форму подбора, отображая только те материалы, по которым есть фактический остаток на складе. Попытка применить для этого стандартный метод УстановитьОтбор() с логическим выражением вида Остаток > 0 приводит к синтаксической ошибке платформы.

Разберем причины такого поведения платформы 1С 7.7 и рассмотрим практические варианты реализации фильтрации номенклатуры по положительным остаткам.

Почему не работает метод УстановитьОтбор

Проанализируем ограничения платформы 1С 7.7:

  1. Метод УстановитьОтбор(<ИмяРеквизита>, <Значение>) работает исключительно по принципу точного равенства конкретному значению реквизита справочника, для которого в конфигураторе включен флаг Отбор. Он не поддерживает логические операторы сравнения (>, <, <>) или диапазоны.
  2. Остатки материалов в бухгалтерском учете не хранятся в реквизитах самого справочника, а рассчитываются по проводкам на счете 10 через регистры бухгалтерских итогов. Следовательно, динамически отфильтровать стандартный список справочника напрямую по вычисляемому полю нельзя.

Вариант 1. Использование метода ИспользоватьСписокЭлементов

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

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


// В модуле документа при вызове подбора
Процедура ПоКнопкеПодбор()
    Перем БИ, СпМатериалов, СкладДокумента;
    
    СкладДокумента = МестоХранения;
    СпМатериалов = СоздатьОбъект("СписокЗначений");
    
    // Рассчитываем остатки материалов по счету 10 на складе документа
    БИ = СоздатьОбъект("БухгалтерскиеИтоги");
    БИ.ИспользоватьСубконто(ВидыСубконто.Материалы);
    БИ.ИспользоватьСубконто(ВидыСубконто.МестаХранения, СкладДокумента, 2);
    БИ.ВыполнитьЗапрос(, ДатаДок, "10");
    
    БИ.ВыбратьСубконто(1);
    Пока БИ.ПолучитьСубконто(1) = 1 Цикл
        // Проверяем конечное дебетовое сальдо по количеству
        Если БИ.СКД("К") > 0 Тогда
            СпМатериалов.ДобавитьЗначение(БИ.Субконто(1));
        КонецЕсли;
    КонецЦикла;
    
    // Открываем форму подбора и передаем сформированный список
    ОткрытьПодбор("Справочник.Материалы", "ДляПодбора", Контекст, 0, СпМатериалов);
КонецПроцедуры

Теперь разберем, как обработать полученный список в модуле формы подбора справочника Материалы (в форме с синонимом ДляПодбора):


Процедура ПриОткрытии()
    // Проверяем переданный параметр формы
    Если ТипЗначенияСтр(Форма.Параметр) = "СписокЗначений" Тогда
        // Отключаем иерархический просмотр, чтобы видеть плоский список отобранных позиций
        ИерархическийПросмотр(0);
        // Применяем фильтр к списку справочника
        ИспользоватьСписокЭлементов(Форма.Параметр);
    КонецЕсли;
КонецПроцедуры

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

Вариант 2. Создание формы подбора на основе Таблицы Значений

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

  1. В левой части размещается дерево групп справочника Материалы.
  2. В правой части размещается элемент диалога ТаблицаЗначений, куда динамически выводятся материалы выбранной группы, имеющие остаток на указанном складе.

Разберем алгоритм работы такой формы:

  1. При открытии формы считываются остатки по всем материалам текущего склада в общую таблицу значений.
  2. При смене текущей папки в левой панели правая таблица значений фильтруется по родителю с отбором строк, где колонка остатка больше нуля.
  3. При двойном клике по строке таблицы значений вызывается процедура передачи выбранной позиции в документ через предопределенную процедуру ОбработкаПодбора() контекста документа-владельца.

Вариант 3. Проверка остатка в процедуре ОбработкаПодбора

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

Посмотрим на пример обработки в модуле формы документа Требование-накладная:


Процедура ОбработкаПодбора(ВыбЭлем, КонтекстФормы)
    Перем БИ, Остаток;
    
    // Рассчитываем остаток выбранного материала на складе
    БИ = СоздатьОбъект("БухгалтерскиеИтоги");
    БИ.ИспользоватьСубконто(ВидыСубконто.Материалы, ВыбЭлем, 2);
    БИ.ИспользоватьСубконто(ВидыСубконто.МестаХранения, МестоХранения, 2);
    БИ.ВыполнитьЗапрос(ДатаДок, ДатаДок, "10");
    
    Остаток = БИ.СКД("К");
    
    Если Остаток <= 0 Тогда
        Предупреждение("Материала """ + ВыбЭлем.Наименование + """ нет в наличии на складе!");
        Возврат;
    КонецЕсли;
    
    // Добавление строки в табличную часть документа
    НоваяСтрока();
    Материал = ВыбЭлем;
    Количество = 1;
КонецПроцедуры

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

← На главную