При разработке и доработке учетных механизмов в платформе 1С:Предприятие 7.7 разработчики часто сталкиваются с задачей отбора элементов справочника в форме списка или форме подбора. Типичный пример — подбор партий номенклатуры в документ, где требуется скрыть элементы с незаполненным реквизитом Поставщик.
Разберем природу этого ограничения и рассмотрим эффективные варианты реализации подбора без пустых значений.
Проанализируем, почему стандартный метод ИспользоватьРеквизит() не позволяет решить задачу напрямую:
Реквизит = Значение.ПолучитьПустоеЗначение("Справочник.Контрагенты")), то инвертировать это условие стандартный диалог списка не позволяет.Оптимальным и наиболее производительным решением в 1С 7.7 является отказ от стандартной формы списка справочника в пользу отдельной формы подбора (обработки), на которой размещен элемент диалога ТаблицаЗначений.
Разберем по шагам создание такой формы:
ТЗПартий.Запрос, который выбирает партии с остатками по регистру или напрямую из справочника с фильтрацией пустых контрагентов.Посмотрим на пример текста модуля формы подбора:
Процедура ЗаполнитьПартии()
Перем Запрос, ТекстЗапроса;
ТЗПартий.Очистить();
ТЗПартий.НоваяКолонка("Партия", "Справочник.Партии");
ТЗПартий.НоваяКолонка("Поставщик", "Справочник.Контрагенты");
ТЗПартий.НоваяКолонка("Остаток", "Число", 15, 3);
Запрос = СоздатьОбъект("Запрос");
ТекстЗапроса = "
|//{{ЗАПРОС(Сформировать)
|Период с ТекущаяДата() по ТекущаяДата();
|Номенклатура = Регистр.ОстаткиТоваров.Номенклатура;
|Партия = Регистр.ОстаткиТоваров.Партия;
|Количество = Регистр.ОстаткиТоваров.ОстатокТовара;
|Функция КонОст = КонОст(Количество);
|Группировка Партия без групп;
|Условие (Номенклатура = ВыбНоменклатура);
|Условие (Не(Партия.Поставщик = ПолучитьПустоеЗначение(""Справочник.Контрагенты"")));
|Условие (КонОст > 0);
|//}}ЗАПРОС
|";
Если Запрос.Выполнить(ТекстЗапроса) = 1 Тогда
Пока Запрос.Группировка(1) = 1 Цикл
ТЗПартий.НоваяСтрока();
ТЗПартий.Партия = Запрос.Партия;
ТЗПартий.Поставщик = Запрос.Партия.Поставщик;
ТЗПартий.Остаток = Запрос.КонОст;
КонецЦикла;
КонецЕсли;
КонецПроцедуры
При двойном щелчке по строке таблицы значений вызывается процедура переноса данных в исходный документ:
Процедура ПриВыбореСтрокиТЗ()
Если ТЗПартий.ТекущаяСтрока() > 0 Тогда
КонтекстДокумента.Партия = ТЗПартий.ПолучитьЗначение(ТЗПартий.ТекущаяСтрока(), "Партия");
Форма.Закрыть();
КонецЕсли;
КонецПроцедуры
Если требуется сохранить типовой интерфейс формы списка справочника Партии, можно использовать механизм отбора по специальному числовому реквизиту:
Партии и добавляем реквизит ЕстьПоставщик (Число, длина 1).ПриЗаписи() прописываем автоматическое заполнение флага:
Процедура ПриЗаписи()
Если ПустоеЗначение(Поставщик) = 1 Тогда
ЕстьПоставщик = 0;
Иначе
ЕстьПоставщик = 1;
КонецЕсли;
КонецПроцедуры
Для существующих элементов выполняется разовая обработка перезаписи реквизита. После этого в форме списка справочника при открытии в режиме выбора можно применить стандартный отбор:
ИспользоватьРеквизит("ЕстьПоставщик", 1);
При больших объемах номенклатуры и партий выгрузка больших выборок в память через стандартный Запрос может требовать оптимизации. В таком случае применяются внешние компоненты:
ODBCRecordset и элемента управления ПолеТаблицы. Это позволяет отправлять прямой SQL-запрос к базе данных с фильтром WHERE RTRIM(sp.ID_POSTAVSCHIK) <> $ПустоеИД и динамически отображать только нужные партии без блокировок и тормозов.Таким образом, переход на специализированную форму подбора с Таблицей Значений полностью решает задачу фильтрации партий без поставщика, снимает ограничения стандартного диалога и существенно ускоряет работу пользователей в 1С:Предприятии 7.7.