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