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