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