В процессе адаптации типовых конфигураций «1С:Предприятие 8.3» (например, «Бухгалтерия предприятия 3.0») под нужды конкретного предприятия часто возникает задача ограничения списка выбора тех или иных справочников. Типичный пример — добавление нового реквизита для учета Государственного оборонного заказа (ГОЗ) и необходимость фильтровать договоры контрагентов так, чтобы пользователь видел только договоры с определенным видом («С покупателем») и установленным признаком принадлежности к ГОЗ.
В этой статье мы подробно проанализируем ошибки, которые часто совершают начинающие разработчики при реализации этой задачи, и разберем по шагам три надежных способа настройки отбора: декларативный (без кода), программный (через переопределение выбора) и наиболее оптимальный — через программное заполнение параметров выбора при создании формы.
Рассмотрим код, который попытался использовать автор темы на форуме:
&НаКлиенте
Процедура ДоговорГОЗНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
ВернутьВидДоговора();
КонецПроцедуры
&НаСервере
Функция ВернутьВидДоговора()
Возврат Объект.ДоговорГОЗ.ВидДоговора = "С покупателем";
КонецФункции
Проанализируем эту ситуацию и выделим две ключевые методологические ошибки, из-за которых данный алгоритм принципиально не мог работать:
ВидДоговора в справочнике ДоговорыКонтрагентов имеет тип ссылки на перечисление (ПеречислениеСсылка.ВидыДоговоровКонтрагентов). Разработчик попытался сравнить его с обычной строкой "С покупателем". Такое сравнение в системе 1С всегда будет возвращать Ложь. Для корректной проверки необходимо обращаться к предопределенным значениям перечисления.Истина или Ложь) из серверной функции в обработчик события элемента формы никак не влияет на поведение платформы. Обработчик ожидает либо отмены стандартного действия путем установки параметра СтандартнаяОбработка = Ложь и последующего ручного открытия нужной формы, либо динамической модификации параметров самого элемента.Выясним самый простой, быстрый и рекомендуемый платформой 1С метод решения задачи. Если условия фильтрации статичны и не зависят от других реквизитов на форме, писать программный код вообще не требуется. Все настройки можно выполнить непосредственно в конфигураторе.
Разберем по шагам, как это сделать:
ДоговорГОЗ (ссылка на справочник ДоговорыКонтрагентов).Отбор.ВидДоговора. В колонке «Значение» выберите из перечисления ВидыДоговоровКонтрагентов значение С покупателем.Отбор.ГОЗ (или имя вашего булева реквизита в справочнике договоров, отвечающего за ГОЗ), а в колонке «Значение» установите Истина.Преимущества метода: Конфигурация остается максимально близкой к типовой, не создаются лишние обработчики событий на формах, а платформа автоматически применяет эти фильтры во всех стандартных механизмах, включая автоподбор при вводе текста с клавиатуры.
Если вам по какой-то причине необходимо тонко управлять процессом открытия формы выбора (например, динамически менять условия отбора в зависимости от других реквизитов документа на клиенте), рассмотрим программный вариант с использованием события НачалоВыбора.
Посмотрим на пример правильной реализации этого механизма без избыточного использования асинхронных вызовов:
&НаКлиенте
Процедура ДоговорГОЗНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
// Отменяем стандартное открытие формы платформой
СтандартнаяОбработка = Ложь;
// Формируем структуру параметров для открываемой формы выбора
ПараметрыФормы = Новый Структура;
// Задаем структуру отбора
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("ВидДоговора", ПредопределенноеЗначение("Перечисление.ВидыДоговоровКонтрагентов.СПокупателем"));
СтруктураОтбора.Вставить("ГОЗ", Истина);
// Помещаем отбор в параметры формы выбора
ПараметрыФормы.Вставить("Отбор", СтруктураОтбора);
// Открываем форму выбора справочника договоров.
// Передавая "Элемент" третьим параметром, мы назначаем его владельцем формы выбора.
// Платформа автоматически вернет выбранное пользователем значение в это поле формы.
ОткрытьФорму("Справочник.ДоговорыКонтрагентов.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры
Важное примечание: Обратите внимание на использование функции ПредопределенноеЗначение(). На клиенте мы не можем напрямую обратиться к менеджеру перечислений вроде Перечисления.ВидыДоговоровКонтрагентов.СПокупателем, так как метаданные недоступны в контексте тонкого клиента напрямую. Использование ПредопределенноеЗначение() — это наиболее грамотный и быстрый способ получить ссылку на значение перечисления на стороне клиента.
Несмотря на работоспособность второго способа, у него есть один существенный недостаток. Когда мы устанавливаем СтандартнаяОбработка = Ложь в событии НачалоВыбора, мы полностью отключаем стандартное поведение поля ввода. Из-за этого перестает работать удобный механизм автоподбора (когда пользователь начинает вводить первые буквы названия договора прямо в поле, и система предлагает подходящие варианты).
Чтобы сохранить все преимущества платформенного автоподбора и при этом установить жесткие отборы программно, проанализируем третий способ — установку параметров выбора при создании формы на сервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Инициализируем массив для параметров выбора элемента формы
МассивПараметров = Новый Массив;
// Добавляем параметр для фильтрации по виду договора
МассивПараметров.Добавить(Новый ПараметрВыбора("Отбор.ВидДоговора", Перечисления.ВидыДоговоровКонтрагентов.СПокупателем));
// Добавляем параметр для фильтрации по признаку ГОЗ
МассивПараметров.Добавить(Новый ПараметрВыбора("Отбор.ГОЗ", Истина));
// Применяем настройки к элементу формы.
// Используем ФиксированныйМассив для корректной работы платформенных механизмов
Элементы.ДоговорГОЗ.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
КонецПроцедуры
В этом сценарии нам вообще не требуется прописывать обработчик НачалоВыбора на клиенте. Платформа самостоятельно считает заданные нами параметры при открытии формы выбора и при вводе текста по строке, гарантируя пользователю максимально комфортную и безошибочную работу.
При решении задач автоматизации расчетов по Государственному оборонному заказу важно понимать контекст архитектуры метаданных 1С:
Отбор.ГОЗ = Истина работать не будет, так как дополнительные реквизиты хранятся в отдельной табличной части, а не в реквизитах шапки справочника. Наш пример ориентирован на ситуацию, когда реквизит добавлен физически в конфигураторе.Используя предложенные методики, вы сможете легко и безошибочно настраивать любые отборы для связанных справочников в ваших управляемых формах 1С.