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