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