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