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